nport 2.0.7 โ 2.1.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/CHANGELOG.md +173 -0
- package/README.md +42 -32
- package/dist/analytics.d.ts +59 -0
- package/dist/analytics.js +193 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api.d.ts +20 -0
- package/dist/api.js +85 -0
- package/dist/api.js.map +1 -0
- package/dist/args.d.ts +44 -0
- package/dist/args.js +127 -0
- package/dist/args.js.map +1 -0
- package/dist/bin-manager.d.ts +1 -0
- package/dist/bin-manager.js +209 -0
- package/dist/bin-manager.js.map +1 -0
- package/dist/binary.d.ts +42 -0
- package/dist/binary.js +119 -0
- package/dist/binary.js.map +1 -0
- package/dist/config-manager.d.ts +54 -0
- package/dist/config-manager.js +129 -0
- package/dist/config-manager.js.map +1 -0
- package/dist/config.d.ts +25 -0
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts +61 -0
- package/dist/constants.js +86 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/lang.d.ts +38 -0
- package/dist/lang.js +217 -0
- package/dist/lang.js.map +1 -0
- package/dist/state.d.ts +82 -0
- package/dist/state.js +139 -0
- package/dist/state.js.map +1 -0
- package/dist/tunnel.d.ts +16 -0
- package/dist/tunnel.js +101 -0
- package/dist/tunnel.js.map +1 -0
- package/dist/types/analytics.d.ts +91 -0
- package/dist/types/analytics.js +8 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/config.d.ts +89 -0
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/i18n.d.ts +75 -0
- package/dist/types/i18n.js +5 -0
- package/dist/types/i18n.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/tunnel.d.ts +74 -0
- package/dist/types/tunnel.js +8 -0
- package/dist/types/tunnel.js.map +1 -0
- package/dist/types/version.d.ts +25 -0
- package/dist/types/version.js +5 -0
- package/dist/types/version.js.map +1 -0
- package/dist/ui.d.ts +54 -0
- package/dist/ui.js +120 -0
- package/dist/ui.js.map +1 -0
- package/dist/version.d.ts +16 -0
- package/dist/version.js +49 -0
- package/dist/version.js.map +1 -0
- package/package.json +18 -7
- package/scripts/postinstall.js +25 -0
- package/index.js +0 -110
- package/src/analytics.js +0 -265
- package/src/api.js +0 -104
- package/src/args.js +0 -122
- package/src/bin-manager.js +0 -379
- package/src/binary.js +0 -126
- package/src/config-manager.js +0 -139
- package/src/config.js +0 -88
- package/src/lang.js +0 -293
- package/src/state.js +0 -115
- package/src/tunnel.js +0 -116
- package/src/ui.js +0 -103
- package/src/version.js +0 -56
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,137 @@ All notable changes to NPort will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.1.1] - 2026-01-27
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- ๐ **NPM Package Build**: Fixed missing `dist/` folder in published package
|
|
12
|
+
- Added build step to npm-publish workflow before publishing
|
|
13
|
+
- Package now includes compiled JavaScript files correctly
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- ๐ **CI/CD Workflows**: Added GitHub Actions for automated deployments
|
|
17
|
+
- `ci.yml`: Runs tests on push to main and pull requests
|
|
18
|
+
- `deploy-server.yml`: Auto-deploys Cloudflare Worker on server changes
|
|
19
|
+
- `deploy-website.yml`: Auto-deploys website to Cloudflare Pages on changes
|
|
20
|
+
- ๐งช **Server Test Configuration**: Fixed Vitest config for CI environment
|
|
21
|
+
- Added miniflare bindings for test environment variables
|
|
22
|
+
- Tests now pass in CI without `.dev.vars` file
|
|
23
|
+
- โ๏ธ **Wrangler Configuration**: Added `preview_urls` setting to suppress warnings
|
|
24
|
+
|
|
25
|
+
## [2.1.0] - 2026-01-27
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- ๐ท **Full TypeScript Migration**: Complete rewrite of CLI and Server in TypeScript
|
|
29
|
+
- Strict type checking enabled across the entire codebase
|
|
30
|
+
- All modules converted from JavaScript to TypeScript
|
|
31
|
+
- Type-safe interfaces for configuration, tunnels, analytics, and i18n
|
|
32
|
+
- Better IDE support with IntelliSense and autocompletion
|
|
33
|
+
- ๐ **Comprehensive Documentation**: New docs folder with detailed guides
|
|
34
|
+
- `docs/ARCHITECTURE.md`: System overview, component diagrams, and data flow
|
|
35
|
+
- `docs/API.md`: Complete API reference with endpoints and examples
|
|
36
|
+
- `docs/CONTRIBUTING.md`: Contribution guidelines and development setup
|
|
37
|
+
- ๐ค **AI Context Support**: Added `.ai/context.md` for AI-assisted development
|
|
38
|
+
- Project structure and key patterns documented
|
|
39
|
+
- Coding conventions and architecture decisions
|
|
40
|
+
- Makes AI pair programming more effective
|
|
41
|
+
- ๐งช **Unit Testing with Vitest**: Comprehensive test suite for CLI
|
|
42
|
+
- Tests for argument parsing (`tests/args.test.ts`)
|
|
43
|
+
- Tests for version comparison (`tests/version.test.ts`)
|
|
44
|
+
- Tests for state management (`tests/state.test.ts`)
|
|
45
|
+
- Easy to run with `npm test`
|
|
46
|
+
- ๐ **Code Ownership**: Added `.github/CODEOWNERS` file
|
|
47
|
+
- Clear ownership for code review assignments
|
|
48
|
+
- Faster PR reviews with automatic reviewer assignment
|
|
49
|
+
- ๐ **Cursor Rules**: Added `.cursorrules` for consistent AI assistance
|
|
50
|
+
- Project-specific coding conventions
|
|
51
|
+
- TypeScript and naming guidelines
|
|
52
|
+
- Common patterns and anti-patterns
|
|
53
|
+
- ๐ **Auto-download Cloudflared**: Binary downloads automatically on first run
|
|
54
|
+
- No need to run separate install commands
|
|
55
|
+
- Seamless first-time user experience
|
|
56
|
+
- Progress indicator during download
|
|
57
|
+
- ๐ **Protected Subdomain Support**: Enhanced error handling for reserved subdomains
|
|
58
|
+
- User-friendly error message when trying to create protected subdomains (like `api`)
|
|
59
|
+
- Formatted error output matching existing error style
|
|
60
|
+
- Helpful suggestions to use alternative subdomain names
|
|
61
|
+
- Prevents accidental use of backend service subdomains
|
|
62
|
+
- ๐ **TODO Management**: Added `TODO.md` for tracking planned features
|
|
63
|
+
- Move time limit enforcement to backend
|
|
64
|
+
- Update README powered-by section
|
|
65
|
+
- Track terminal link clicks
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
- ๐๏ธ **Project Structure**: Reorganized for better maintainability
|
|
69
|
+
- All source code in `src/` directory
|
|
70
|
+
- Type definitions in `src/types/`
|
|
71
|
+
- Shared constants in `src/constants.ts`
|
|
72
|
+
- Tests in `tests/` directory
|
|
73
|
+
- ๐ฆ **Build System**: Updated to TypeScript compilation
|
|
74
|
+
- Uses `tsc` for compilation
|
|
75
|
+
- Output to `dist/` directory
|
|
76
|
+
- Source maps for debugging
|
|
77
|
+
- ๐ง **Development Workflow**: Improved developer experience
|
|
78
|
+
- `npm run dev` for watch mode
|
|
79
|
+
- `npm run build` for production
|
|
80
|
+
- `npm test` for running tests
|
|
81
|
+
- `npm run lint` for type checking
|
|
82
|
+
- โ๏ธ **System Requirements**: Updated to Node.js 20+
|
|
83
|
+
- Minimum Node.js version: 20.0.0
|
|
84
|
+
- Minimum npm version: 10.0.0
|
|
85
|
+
- Better security and performance with latest LTS
|
|
86
|
+
|
|
87
|
+
### Improved
|
|
88
|
+
- โจ **Better Error Messages**: Enhanced user feedback for protected subdomains
|
|
89
|
+
- Catches `SUBDOMAIN_PROTECTED` errors from backend
|
|
90
|
+
- Formats error messages consistently with other error types
|
|
91
|
+
- Shows actionable options when subdomain is reserved
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
- ๐ **Intel Mac Binary Download**: Fixed cloudflared binary download on Intel Macs
|
|
95
|
+
- Node.js reports architecture as `x64`, not `amd64` - now correctly mapped
|
|
96
|
+
- Fixed ARM64 Macs to download the correct `cloudflared-darwin-arm64.tgz` binary
|
|
97
|
+
- Previously ARM64 Macs were incorrectly downloading the AMD64 binary
|
|
98
|
+
|
|
99
|
+
### Server (v1.1.0)
|
|
100
|
+
- ๐ท **TypeScript Migration**: Server fully converted to TypeScript
|
|
101
|
+
- Type-safe Cloudflare Worker handlers
|
|
102
|
+
- Properly typed API responses
|
|
103
|
+
- Full type coverage for Cloudflare API interactions
|
|
104
|
+
- ๐งช **Server Tests**: Updated test suite for TypeScript
|
|
105
|
+
- Vitest with Cloudflare Workers pool
|
|
106
|
+
- Tests for all API endpoints
|
|
107
|
+
- Scheduled task testing
|
|
108
|
+
- ๐ **Protected Subdomains**: Infrastructure to protect critical subdomains from deletion or overwriting
|
|
109
|
+
- New `PROTECTED_SUBDOMAINS` constant array for easy management of reserved subdomains
|
|
110
|
+
- Default protected subdomain: `api` (reserved for NPort backend service)
|
|
111
|
+
- Easy to add more protected subdomains by updating the array
|
|
112
|
+
- Protected subdomains are blocked at both creation and cleanup stages
|
|
113
|
+
- ๐ก๏ธ **Backend Service Protection**: Prevents accidental deletion or overwriting of production services
|
|
114
|
+
- `api` subdomain is now protected from user creation attempts
|
|
115
|
+
- Scheduled cleanup job skips protected subdomains
|
|
116
|
+
- Returns clear error message when users try to use protected names
|
|
117
|
+
- ๐ง **Manual Cleanup Endpoint**: Added `GET /scheduled` endpoint to manually trigger cleanup
|
|
118
|
+
- Useful for testing and on-demand cleanup
|
|
119
|
+
- Respects protected subdomains configuration
|
|
120
|
+
- Returns JSON response with cleanup results
|
|
121
|
+
|
|
122
|
+
### Technical Details
|
|
123
|
+
- **Type System**:
|
|
124
|
+
- `TunnelConfig`, `TunnelState`, `ConnectionInfo` interfaces
|
|
125
|
+
- `AnalyticsParams`, `VersionInfo`, `I18nStrings` types
|
|
126
|
+
- `LogPatterns` with readonly arrays for constants
|
|
127
|
+
- **ESM Compliance**: All imports use `.js` extensions as required
|
|
128
|
+
- **Constants**: Centralized in `src/constants.ts` with `as const` assertions
|
|
129
|
+
- **Error Handling**: Type-safe error boundaries throughout
|
|
130
|
+
|
|
131
|
+
### Migration
|
|
132
|
+
- Automatic migration - no manual steps required
|
|
133
|
+
- Existing configuration in `~/.nport/config.json` remains compatible
|
|
134
|
+
- All CLI flags and options unchanged
|
|
135
|
+
|
|
136
|
+
### Breaking Changes
|
|
137
|
+
- None - fully backward compatible!
|
|
138
|
+
|
|
8
139
|
## [2.0.7] - 2026-01-14
|
|
9
140
|
|
|
10
141
|
### Added
|
|
@@ -186,6 +317,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
186
317
|
|
|
187
318
|
## Version Upgrade Guide
|
|
188
319
|
|
|
320
|
+
### From 2.0.7 to 2.1.0
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
npm install -g nport@latest
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
**What's New:**
|
|
327
|
+
|
|
328
|
+
1. **Full TypeScript Rewrite**
|
|
329
|
+
- Both CLI and Server now fully typed
|
|
330
|
+
- Better IDE support and autocompletion
|
|
331
|
+
- Catches errors at compile time
|
|
332
|
+
|
|
333
|
+
2. **Comprehensive Documentation**
|
|
334
|
+
- Architecture guide in `docs/ARCHITECTURE.md`
|
|
335
|
+
- API reference in `docs/API.md`
|
|
336
|
+
- Contributing guide in `docs/CONTRIBUTING.md`
|
|
337
|
+
|
|
338
|
+
3. **Unit Testing**
|
|
339
|
+
- Run tests with `npm test`
|
|
340
|
+
- Covers argument parsing, version checks, state management
|
|
341
|
+
|
|
342
|
+
4. **Auto-download Cloudflared**
|
|
343
|
+
- Binary downloads automatically on first `nport` run
|
|
344
|
+
- No separate install step needed
|
|
345
|
+
|
|
346
|
+
5. **AI-Friendly Codebase**
|
|
347
|
+
- `.ai/context.md` for AI assistants
|
|
348
|
+
- `.cursorrules` for consistent AI suggestions
|
|
349
|
+
- JSDoc comments throughout
|
|
350
|
+
|
|
351
|
+
**For Contributors:**
|
|
352
|
+
```bash
|
|
353
|
+
git clone https://github.com/tuanngocptn/nport
|
|
354
|
+
cd nport
|
|
355
|
+
npm install
|
|
356
|
+
npm run build
|
|
357
|
+
npm run dev # Watch mode
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**Breaking Changes:** None - fully backward compatible!
|
|
361
|
+
|
|
189
362
|
### From 2.0.6 to 2.0.7
|
|
190
363
|
|
|
191
364
|
```bash
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
[](https://www.npmjs.com/package/nport)
|
|
7
7
|
[](https://nport.link)
|
|
8
8
|
[](LICENSE)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
9
10
|
|
|
10
11
|
## What is NPort?
|
|
11
12
|
|
|
@@ -269,25 +270,30 @@ Internet โ Cloudflare Edge โ Cloudflare Tunnel โ Your localhost:3000
|
|
|
269
270
|
|
|
270
271
|
## ๐๏ธ Project Structure
|
|
271
272
|
|
|
272
|
-
NPort uses a modular architecture for better maintainability:
|
|
273
|
-
|
|
274
273
|
```
|
|
275
274
|
nport/
|
|
276
|
-
โโโ
|
|
277
|
-
โโโ
|
|
278
|
-
โ โโโ
|
|
279
|
-
โ โโโ api.
|
|
280
|
-
โ โโโ args.
|
|
281
|
-
โ โโโ binary.
|
|
282
|
-
โ โโโ
|
|
283
|
-
โ โโโ
|
|
284
|
-
โ โโโ
|
|
285
|
-
โ
|
|
286
|
-
โ
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
275
|
+
โโโ src/ # TypeScript source files
|
|
276
|
+
โ โโโ index.ts # Entry point
|
|
277
|
+
โ โโโ tunnel.ts # Tunnel orchestration
|
|
278
|
+
โ โโโ api.ts # Backend API client
|
|
279
|
+
โ โโโ args.ts # CLI argument parser
|
|
280
|
+
โ โโโ binary.ts # Cloudflared process manager
|
|
281
|
+
โ โโโ ui.ts # Console UI components
|
|
282
|
+
โ โโโ lang.ts # Multilingual support
|
|
283
|
+
โ โโโ types/ # TypeScript type definitions
|
|
284
|
+
โ โโโ ...
|
|
285
|
+
โ
|
|
286
|
+
โโโ tests/ # Unit tests (vitest)
|
|
287
|
+
โโโ dist/ # Compiled output
|
|
288
|
+
โโโ bin/ # cloudflared binary (downloaded)
|
|
289
|
+
โ
|
|
290
|
+
โโโ server/ # Backend (Cloudflare Worker)
|
|
291
|
+
โโโ website/ # Static landing page
|
|
292
|
+
โโโ docs/ # Documentation
|
|
293
|
+
โ โโโ ARCHITECTURE.md # Technical architecture
|
|
294
|
+
โ โโโ API.md # API reference
|
|
295
|
+
โ โโโ CONTRIBUTING.md # Contribution guide
|
|
296
|
+
โโโ .ai/ # AI context files
|
|
291
297
|
```
|
|
292
298
|
|
|
293
299
|
## ๐ก๏ธ Security
|
|
@@ -370,7 +376,7 @@ Then select your preferred language from the menu.
|
|
|
370
376
|
- ๐บ๐ธ **English** (`en`) - Default
|
|
371
377
|
- ๐ป๐ณ **Vietnamese** (`vi`) - Tiแบฟng Viแปt
|
|
372
378
|
|
|
373
|
-
Want to add your language? Contributions are welcome! Check out
|
|
379
|
+
Want to add your language? Contributions are welcome! Check out the [Contributing Guide](docs/CONTRIBUTING.md).
|
|
374
380
|
|
|
375
381
|
## ๐ค Contributing
|
|
376
382
|
|
|
@@ -382,22 +388,26 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
382
388
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
383
389
|
5. Open a Pull Request
|
|
384
390
|
|
|
385
|
-
|
|
391
|
+
See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) for detailed guidelines.
|
|
392
|
+
|
|
393
|
+
### Development Setup
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
# Clone the repository
|
|
397
|
+
git clone https://github.com/tuanngocptn/nport.git
|
|
398
|
+
cd nport
|
|
399
|
+
|
|
400
|
+
# Install dependencies
|
|
401
|
+
npm install
|
|
386
402
|
|
|
387
|
-
|
|
403
|
+
# Build TypeScript
|
|
404
|
+
npm run build
|
|
388
405
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
3. Add translations to the `TRANSLATIONS` object
|
|
392
|
-
4. Submit a PR!
|
|
406
|
+
# Run tests
|
|
407
|
+
npm test
|
|
393
408
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const TRANSLATIONS = {
|
|
397
|
-
en: { /* English translations */ },
|
|
398
|
-
vi: { /* Vietnamese translations */ },
|
|
399
|
-
es: { /* Your Spanish translations */ },
|
|
400
|
-
};
|
|
409
|
+
# Run CLI locally
|
|
410
|
+
node dist/index.js 3000 -s test
|
|
401
411
|
```
|
|
402
412
|
|
|
403
413
|
## ๐ Support
|
|
@@ -408,7 +418,7 @@ If you find NPort useful, please consider supporting the project:
|
|
|
408
418
|
- โ [Buy me a coffee](https://buymeacoffee.com/tuanngocptn)
|
|
409
419
|
- ๐ฌ Share with your friends and colleagues
|
|
410
420
|
- ๐ [Report bugs](https://github.com/tuanngocptn/nport/issues)
|
|
411
|
-
- ๐ [Add translations](
|
|
421
|
+
- ๐ [Add translations](docs/CONTRIBUTING.md#adding-translations)
|
|
412
422
|
|
|
413
423
|
## ๐ License
|
|
414
424
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Manager
|
|
3
|
+
*/
|
|
4
|
+
declare class AnalyticsManager {
|
|
5
|
+
private userId;
|
|
6
|
+
private sessionId;
|
|
7
|
+
private disabled;
|
|
8
|
+
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Initializes analytics.
|
|
11
|
+
*/
|
|
12
|
+
initialize(): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Gets or creates a persistent user ID.
|
|
15
|
+
*/
|
|
16
|
+
private getUserId;
|
|
17
|
+
/**
|
|
18
|
+
* Generates an anonymous user ID.
|
|
19
|
+
*/
|
|
20
|
+
private generateAnonymousId;
|
|
21
|
+
/**
|
|
22
|
+
* Generates a session ID.
|
|
23
|
+
*/
|
|
24
|
+
private generateSessionId;
|
|
25
|
+
/**
|
|
26
|
+
* Tracks an event.
|
|
27
|
+
*/
|
|
28
|
+
private trackEvent;
|
|
29
|
+
/**
|
|
30
|
+
* Builds GA4 payload.
|
|
31
|
+
*/
|
|
32
|
+
private buildPayload;
|
|
33
|
+
/**
|
|
34
|
+
* Gets system information.
|
|
35
|
+
*/
|
|
36
|
+
private getSystemInfo;
|
|
37
|
+
/**
|
|
38
|
+
* Tracks CLI start.
|
|
39
|
+
*/
|
|
40
|
+
trackCliStart(port: number, subdomain: string, version: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Tracks tunnel creation.
|
|
43
|
+
*/
|
|
44
|
+
trackTunnelCreated(subdomain: string, port: number): void;
|
|
45
|
+
/**
|
|
46
|
+
* Tracks tunnel error.
|
|
47
|
+
*/
|
|
48
|
+
trackTunnelError(errorType: string, errorMessage: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Tracks tunnel shutdown.
|
|
51
|
+
*/
|
|
52
|
+
trackTunnelShutdown(reason: string, durationSeconds: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Tracks update available.
|
|
55
|
+
*/
|
|
56
|
+
trackUpdateAvailable(currentVersion: string, latestVersion: string): void;
|
|
57
|
+
}
|
|
58
|
+
export declare const analytics: AnalyticsManager;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { createHash, randomUUID } from 'crypto';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { ANALYTICS_TIMEOUT } from './constants.js';
|
|
7
|
+
/**
|
|
8
|
+
* Firebase/GA4 Configuration
|
|
9
|
+
*/
|
|
10
|
+
const FIREBASE_CONFIG = {
|
|
11
|
+
measurementId: 'G-8MYXZL6PGD',
|
|
12
|
+
apiSecret: process.env.NPORT_ANALYTICS_SECRET || 'YOUR_API_SECRET_HERE',
|
|
13
|
+
};
|
|
14
|
+
const ANALYTICS_CONFIG = {
|
|
15
|
+
enabled: true,
|
|
16
|
+
debug: process.env.NPORT_DEBUG === 'true',
|
|
17
|
+
timeout: ANALYTICS_TIMEOUT,
|
|
18
|
+
userIdFile: path.join(os.homedir(), '.nport', 'analytics-id'),
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Analytics Manager
|
|
22
|
+
*/
|
|
23
|
+
class AnalyticsManager {
|
|
24
|
+
userId = null;
|
|
25
|
+
sessionId = null;
|
|
26
|
+
disabled = false;
|
|
27
|
+
constructor() {
|
|
28
|
+
if (process.env.NPORT_ANALYTICS === 'false') {
|
|
29
|
+
this.disabled = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Initializes analytics.
|
|
34
|
+
*/
|
|
35
|
+
async initialize() {
|
|
36
|
+
if (this.disabled)
|
|
37
|
+
return;
|
|
38
|
+
if (!FIREBASE_CONFIG.apiSecret || FIREBASE_CONFIG.apiSecret === 'YOUR_API_SECRET_HERE') {
|
|
39
|
+
if (ANALYTICS_CONFIG.debug) {
|
|
40
|
+
console.warn('[Analytics] API secret not configured. Analytics disabled.');
|
|
41
|
+
}
|
|
42
|
+
this.disabled = true;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
this.userId = await this.getUserId();
|
|
47
|
+
this.sessionId = this.generateSessionId();
|
|
48
|
+
if (ANALYTICS_CONFIG.debug) {
|
|
49
|
+
console.log('[Analytics] Initialized successfully');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
this.disabled = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Gets or creates a persistent user ID.
|
|
58
|
+
*/
|
|
59
|
+
async getUserId() {
|
|
60
|
+
try {
|
|
61
|
+
const configDir = path.join(os.homedir(), '.nport');
|
|
62
|
+
if (!fs.existsSync(configDir)) {
|
|
63
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
if (fs.existsSync(ANALYTICS_CONFIG.userIdFile)) {
|
|
66
|
+
const userId = fs.readFileSync(ANALYTICS_CONFIG.userIdFile, 'utf8').trim();
|
|
67
|
+
if (userId)
|
|
68
|
+
return userId;
|
|
69
|
+
}
|
|
70
|
+
const userId = this.generateAnonymousId();
|
|
71
|
+
fs.writeFileSync(ANALYTICS_CONFIG.userIdFile, userId, 'utf8');
|
|
72
|
+
return userId;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return this.generateAnonymousId();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Generates an anonymous user ID.
|
|
80
|
+
*/
|
|
81
|
+
generateAnonymousId() {
|
|
82
|
+
const machineId = [
|
|
83
|
+
os.hostname(),
|
|
84
|
+
os.platform(),
|
|
85
|
+
os.arch(),
|
|
86
|
+
os.homedir(),
|
|
87
|
+
].join('-');
|
|
88
|
+
return createHash('sha256').update(machineId).digest('hex').substring(0, 32);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generates a session ID.
|
|
92
|
+
*/
|
|
93
|
+
generateSessionId() {
|
|
94
|
+
return randomUUID();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Tracks an event.
|
|
98
|
+
*/
|
|
99
|
+
async trackEvent(eventName, params = {}) {
|
|
100
|
+
if (this.disabled || !ANALYTICS_CONFIG.enabled || !this.userId)
|
|
101
|
+
return;
|
|
102
|
+
try {
|
|
103
|
+
const payload = this.buildPayload(eventName, params);
|
|
104
|
+
axios.post(`https://www.google-analytics.com/mp/collect?measurement_id=${FIREBASE_CONFIG.measurementId}&api_secret=${FIREBASE_CONFIG.apiSecret}`, payload, {
|
|
105
|
+
timeout: ANALYTICS_CONFIG.timeout,
|
|
106
|
+
headers: { 'Content-Type': 'application/json' },
|
|
107
|
+
}).catch(() => {
|
|
108
|
+
// Silently fail
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Silently fail
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Builds GA4 payload.
|
|
117
|
+
*/
|
|
118
|
+
buildPayload(eventName, params) {
|
|
119
|
+
return {
|
|
120
|
+
client_id: this.userId,
|
|
121
|
+
events: [
|
|
122
|
+
{
|
|
123
|
+
name: eventName,
|
|
124
|
+
params: {
|
|
125
|
+
session_id: this.sessionId,
|
|
126
|
+
engagement_time_msec: '100',
|
|
127
|
+
...this.getSystemInfo(),
|
|
128
|
+
...params,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Gets system information.
|
|
136
|
+
*/
|
|
137
|
+
getSystemInfo() {
|
|
138
|
+
return {
|
|
139
|
+
os_platform: os.platform(),
|
|
140
|
+
os_version: os.release(),
|
|
141
|
+
os_arch: os.arch(),
|
|
142
|
+
node_version: process.version,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Tracks CLI start.
|
|
147
|
+
*/
|
|
148
|
+
trackCliStart(port, subdomain, version) {
|
|
149
|
+
this.trackEvent('cli_start', {
|
|
150
|
+
port: String(port),
|
|
151
|
+
has_custom_subdomain: subdomain && !subdomain.startsWith('user-'),
|
|
152
|
+
cli_version: version,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Tracks tunnel creation.
|
|
157
|
+
*/
|
|
158
|
+
trackTunnelCreated(subdomain, port) {
|
|
159
|
+
this.trackEvent('tunnel_created', {
|
|
160
|
+
subdomain_type: subdomain.startsWith('user-') ? 'random' : 'custom',
|
|
161
|
+
port: String(port),
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Tracks tunnel error.
|
|
166
|
+
*/
|
|
167
|
+
trackTunnelError(errorType, errorMessage) {
|
|
168
|
+
this.trackEvent('tunnel_error', {
|
|
169
|
+
error_type: errorType,
|
|
170
|
+
error_message: errorMessage.substring(0, 100),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Tracks tunnel shutdown.
|
|
175
|
+
*/
|
|
176
|
+
trackTunnelShutdown(reason, durationSeconds) {
|
|
177
|
+
this.trackEvent('tunnel_shutdown', {
|
|
178
|
+
shutdown_reason: reason,
|
|
179
|
+
duration_seconds: String(Math.floor(durationSeconds)),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Tracks update available.
|
|
184
|
+
*/
|
|
185
|
+
trackUpdateAvailable(currentVersion, latestVersion) {
|
|
186
|
+
this.trackEvent('update_available', {
|
|
187
|
+
current_version: currentVersion,
|
|
188
|
+
latest_version: latestVersion,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export const analytics = new AnalyticsManager();
|
|
193
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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"}
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TunnelResponse } from './types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* API Client
|
|
4
|
+
*
|
|
5
|
+
* Handles all communication with the NPort backend service.
|
|
6
|
+
*/
|
|
7
|
+
export declare class APIClient {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new Cloudflare tunnel via the backend API.
|
|
10
|
+
*/
|
|
11
|
+
static createTunnel(subdomain: string, backendUrl?: string | null): Promise<TunnelResponse>;
|
|
12
|
+
/**
|
|
13
|
+
* Deletes an existing tunnel.
|
|
14
|
+
*/
|
|
15
|
+
static deleteTunnel(subdomain: string, tunnelId: string, backendUrl?: string | null): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Transforms API errors into user-friendly messages.
|
|
18
|
+
*/
|
|
19
|
+
private static handleError;
|
|
20
|
+
}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { CONFIG } from './config.js';
|
|
4
|
+
import { state } from './state.js';
|
|
5
|
+
/**
|
|
6
|
+
* API Client
|
|
7
|
+
*
|
|
8
|
+
* Handles all communication with the NPort backend service.
|
|
9
|
+
*/
|
|
10
|
+
export class APIClient {
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new Cloudflare tunnel via the backend API.
|
|
13
|
+
*/
|
|
14
|
+
static async createTunnel(subdomain, backendUrl = null) {
|
|
15
|
+
const url = backendUrl || CONFIG.BACKEND_URL;
|
|
16
|
+
try {
|
|
17
|
+
const { data } = await axios.post(url, { subdomain });
|
|
18
|
+
if (!data.success) {
|
|
19
|
+
throw new Error(data.error || 'Unknown error from backend');
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
tunnelId: data.tunnelId,
|
|
23
|
+
tunnelToken: data.tunnelToken,
|
|
24
|
+
url: data.url,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw this.handleError(error, subdomain);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Deletes an existing tunnel.
|
|
33
|
+
*/
|
|
34
|
+
static async deleteTunnel(subdomain, tunnelId, backendUrl = null) {
|
|
35
|
+
const url = backendUrl || CONFIG.BACKEND_URL;
|
|
36
|
+
await axios.delete(url, {
|
|
37
|
+
data: { subdomain, tunnelId },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Transforms API errors into user-friendly messages.
|
|
42
|
+
*/
|
|
43
|
+
static handleError(error, subdomain) {
|
|
44
|
+
const errorMsg = error.response?.data?.error;
|
|
45
|
+
if (errorMsg) {
|
|
46
|
+
if (errorMsg.includes('SUBDOMAIN_PROTECTED:')) {
|
|
47
|
+
return new Error(`Subdomain "${subdomain}" is already taken or in use.\n\n` +
|
|
48
|
+
chalk.yellow('๐ก Try one of these options:\n') +
|
|
49
|
+
chalk.gray(' 1. Choose a different subdomain: ') +
|
|
50
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT} -s ${subdomain}-v2\n`) +
|
|
51
|
+
chalk.gray(' 2. Use a random subdomain: ') +
|
|
52
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT}\n`) +
|
|
53
|
+
chalk.gray(' 3. Wait a few minutes and retry if you just stopped a tunnel with this name'));
|
|
54
|
+
}
|
|
55
|
+
if (errorMsg.includes('SUBDOMAIN_IN_USE:') ||
|
|
56
|
+
errorMsg.includes('currently in use') ||
|
|
57
|
+
errorMsg.includes('already exists and is currently active')) {
|
|
58
|
+
return new Error(chalk.red(`โ Subdomain "${subdomain}" is already in use!\n\n`) +
|
|
59
|
+
chalk.yellow('๐ก This subdomain is currently being used by another active tunnel.\n\n') +
|
|
60
|
+
chalk.white('Choose a different subdomain:\n') +
|
|
61
|
+
chalk.gray(' 1. Add a suffix: ') +
|
|
62
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT} -s ${subdomain}-2\n`) +
|
|
63
|
+
chalk.gray(' 2. Try a variation: ') +
|
|
64
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT} -s my-${subdomain}\n`) +
|
|
65
|
+
chalk.gray(' 3. Use random name: ') +
|
|
66
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT}\n`));
|
|
67
|
+
}
|
|
68
|
+
if (errorMsg.includes('already have a tunnel') || errorMsg.includes('[1013]')) {
|
|
69
|
+
return new Error(`Subdomain "${subdomain}" is already taken or in use.\n\n` +
|
|
70
|
+
chalk.yellow('๐ก Try one of these options:\n') +
|
|
71
|
+
chalk.gray(' 1. Choose a different subdomain: ') +
|
|
72
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT} -s ${subdomain}-v2\n`) +
|
|
73
|
+
chalk.gray(' 2. Use a random subdomain: ') +
|
|
74
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT}\n`) +
|
|
75
|
+
chalk.gray(' 3. Wait a few minutes and retry if you just stopped a tunnel with this name'));
|
|
76
|
+
}
|
|
77
|
+
return new Error(`Backend Error: ${errorMsg}`);
|
|
78
|
+
}
|
|
79
|
+
if (error.response) {
|
|
80
|
+
return new Error(`Backend Error: ${JSON.stringify(error.response.data, null, 2)}`);
|
|
81
|
+
}
|
|
82
|
+
return error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|