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.
Files changed (77) hide show
  1. package/CHANGELOG.md +173 -0
  2. package/README.md +42 -32
  3. package/dist/analytics.d.ts +59 -0
  4. package/dist/analytics.js +193 -0
  5. package/dist/analytics.js.map +1 -0
  6. package/dist/api.d.ts +20 -0
  7. package/dist/api.js +85 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/args.d.ts +44 -0
  10. package/dist/args.js +127 -0
  11. package/dist/args.js.map +1 -0
  12. package/dist/bin-manager.d.ts +1 -0
  13. package/dist/bin-manager.js +209 -0
  14. package/dist/bin-manager.js.map +1 -0
  15. package/dist/binary.d.ts +42 -0
  16. package/dist/binary.js +119 -0
  17. package/dist/binary.js.map +1 -0
  18. package/dist/config-manager.d.ts +54 -0
  19. package/dist/config-manager.js +129 -0
  20. package/dist/config-manager.js.map +1 -0
  21. package/dist/config.d.ts +25 -0
  22. package/dist/config.js +59 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/constants.d.ts +61 -0
  25. package/dist/constants.js +86 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.js +92 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lang.d.ts +38 -0
  31. package/dist/lang.js +217 -0
  32. package/dist/lang.js.map +1 -0
  33. package/dist/state.d.ts +82 -0
  34. package/dist/state.js +139 -0
  35. package/dist/state.js.map +1 -0
  36. package/dist/tunnel.d.ts +16 -0
  37. package/dist/tunnel.js +101 -0
  38. package/dist/tunnel.js.map +1 -0
  39. package/dist/types/analytics.d.ts +91 -0
  40. package/dist/types/analytics.js +8 -0
  41. package/dist/types/analytics.js.map +1 -0
  42. package/dist/types/config.d.ts +89 -0
  43. package/dist/types/config.js +8 -0
  44. package/dist/types/config.js.map +1 -0
  45. package/dist/types/i18n.d.ts +75 -0
  46. package/dist/types/i18n.js +5 -0
  47. package/dist/types/i18n.js.map +1 -0
  48. package/dist/types/index.d.ts +10 -0
  49. package/dist/types/index.js +7 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/types/tunnel.d.ts +74 -0
  52. package/dist/types/tunnel.js +8 -0
  53. package/dist/types/tunnel.js.map +1 -0
  54. package/dist/types/version.d.ts +25 -0
  55. package/dist/types/version.js +5 -0
  56. package/dist/types/version.js.map +1 -0
  57. package/dist/ui.d.ts +54 -0
  58. package/dist/ui.js +120 -0
  59. package/dist/ui.js.map +1 -0
  60. package/dist/version.d.ts +16 -0
  61. package/dist/version.js +49 -0
  62. package/dist/version.js.map +1 -0
  63. package/package.json +18 -7
  64. package/scripts/postinstall.js +25 -0
  65. package/index.js +0 -110
  66. package/src/analytics.js +0 -265
  67. package/src/api.js +0 -104
  68. package/src/args.js +0 -122
  69. package/src/bin-manager.js +0 -379
  70. package/src/binary.js +0 -126
  71. package/src/config-manager.js +0 -139
  72. package/src/config.js +0 -88
  73. package/src/lang.js +0 -293
  74. package/src/state.js +0 -115
  75. package/src/tunnel.js +0 -116
  76. package/src/ui.js +0 -103
  77. package/src/version.js +0 -56
@@ -0,0 +1,129 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import os from 'os';
4
+ /**
5
+ * Configuration Manager
6
+ *
7
+ * Handles persistent storage of user preferences in ~/.nport/config.json.
8
+ */
9
+ class ConfigManager {
10
+ configDir;
11
+ configFile;
12
+ oldLangFile;
13
+ config;
14
+ constructor() {
15
+ this.configDir = path.join(os.homedir(), '.nport');
16
+ this.configFile = path.join(this.configDir, 'config.json');
17
+ this.oldLangFile = path.join(this.configDir, 'lang');
18
+ this.config = this.loadConfig();
19
+ this.migrateOldConfig();
20
+ }
21
+ /**
22
+ * Loads configuration from the JSON file.
23
+ */
24
+ loadConfig() {
25
+ try {
26
+ if (fs.existsSync(this.configFile)) {
27
+ const data = fs.readFileSync(this.configFile, 'utf8');
28
+ return JSON.parse(data);
29
+ }
30
+ }
31
+ catch {
32
+ console.warn('Warning: Could not load config file, using defaults');
33
+ }
34
+ return {};
35
+ }
36
+ /**
37
+ * Migrates old configuration files to the new unified format.
38
+ */
39
+ migrateOldConfig() {
40
+ try {
41
+ if (!this.config.language && fs.existsSync(this.oldLangFile)) {
42
+ const oldLang = fs.readFileSync(this.oldLangFile, 'utf8').trim();
43
+ if (oldLang && ['en', 'vi'].includes(oldLang)) {
44
+ this.config.language = oldLang;
45
+ this.saveConfig();
46
+ try {
47
+ fs.unlinkSync(this.oldLangFile);
48
+ }
49
+ catch {
50
+ // Ignore if can't delete
51
+ }
52
+ }
53
+ }
54
+ }
55
+ catch {
56
+ // Ignore migration errors
57
+ }
58
+ }
59
+ /**
60
+ * Saves the current configuration to disk.
61
+ */
62
+ saveConfig() {
63
+ try {
64
+ if (!fs.existsSync(this.configDir)) {
65
+ fs.mkdirSync(this.configDir, { recursive: true });
66
+ }
67
+ fs.writeFileSync(this.configFile, JSON.stringify(this.config, null, 2), 'utf8');
68
+ return true;
69
+ }
70
+ catch {
71
+ console.warn('Warning: Could not save configuration');
72
+ return false;
73
+ }
74
+ }
75
+ /**
76
+ * Gets the saved backend URL.
77
+ */
78
+ getBackendUrl() {
79
+ return this.config.backendUrl ?? null;
80
+ }
81
+ /**
82
+ * Sets or clears the backend URL.
83
+ */
84
+ setBackendUrl(url) {
85
+ if (!url) {
86
+ delete this.config.backendUrl;
87
+ }
88
+ else {
89
+ this.config.backendUrl = url;
90
+ }
91
+ return this.saveConfig();
92
+ }
93
+ /**
94
+ * Gets the saved language preference.
95
+ */
96
+ getLanguage() {
97
+ return this.config.language ?? null;
98
+ }
99
+ /**
100
+ * Sets or clears the language preference.
101
+ */
102
+ setLanguage(lang) {
103
+ if (!lang) {
104
+ delete this.config.language;
105
+ }
106
+ else {
107
+ this.config.language = lang;
108
+ }
109
+ return this.saveConfig();
110
+ }
111
+ /**
112
+ * Gets a copy of all configuration.
113
+ */
114
+ getAll() {
115
+ return { ...this.config };
116
+ }
117
+ /**
118
+ * Clears all configuration.
119
+ */
120
+ clear() {
121
+ this.config = {};
122
+ return this.saveConfig();
123
+ }
124
+ }
125
+ /**
126
+ * Singleton instance
127
+ */
128
+ export const configManager = new ConfigManager();
129
+ //# sourceMappingURL=config-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../src/config-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { AppConfig, PlatformConfig, PathsConfig, LogPatterns, NetworkConfig } from './types/index.js';
2
+ /**
3
+ * Application configuration constants
4
+ */
5
+ export declare const CONFIG: AppConfig;
6
+ /**
7
+ * Platform-specific configuration
8
+ */
9
+ export declare const PLATFORM: PlatformConfig;
10
+ /**
11
+ * File system paths
12
+ */
13
+ export declare const PATHS: PathsConfig;
14
+ /**
15
+ * Log patterns for filtering cloudflared output
16
+ */
17
+ export declare const LOG_PATTERNS: LogPatterns;
18
+ /**
19
+ * Network warning configuration
20
+ */
21
+ export declare const NETWORK_CONFIG: NetworkConfig;
22
+ /**
23
+ * Tunnel timeout in milliseconds
24
+ */
25
+ export declare const TUNNEL_TIMEOUT_MS: number;
package/dist/config.js ADDED
@@ -0,0 +1,59 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { createRequire } from 'module';
4
+ import { DEFAULT_BACKEND_URL, DEFAULT_PORT, SUBDOMAIN_PREFIX, TUNNEL_TIMEOUT_HOURS, UPDATE_CHECK_TIMEOUT, LOG_PATTERNS as SHARED_LOG_PATTERNS, NETWORK_WARNING, } from './constants.js';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(path.dirname(__filename));
7
+ const require = createRequire(import.meta.url);
8
+ const packageJson = require('../package.json');
9
+ /**
10
+ * Gets the backend URL based on priority order.
11
+ */
12
+ function getBackendUrl() {
13
+ if (process.env.NPORT_BACKEND_URL) {
14
+ return process.env.NPORT_BACKEND_URL;
15
+ }
16
+ return DEFAULT_BACKEND_URL;
17
+ }
18
+ /**
19
+ * Application configuration constants
20
+ */
21
+ export const CONFIG = {
22
+ PACKAGE_NAME: packageJson.name,
23
+ CURRENT_VERSION: packageJson.version,
24
+ BACKEND_URL: getBackendUrl(),
25
+ DEFAULT_PORT,
26
+ SUBDOMAIN_PREFIX,
27
+ TUNNEL_TIMEOUT_HOURS,
28
+ UPDATE_CHECK_TIMEOUT,
29
+ };
30
+ /**
31
+ * Platform-specific configuration
32
+ */
33
+ export const PLATFORM = {
34
+ IS_WINDOWS: process.platform === 'win32',
35
+ BIN_NAME: process.platform === 'win32' ? 'cloudflared.exe' : 'cloudflared',
36
+ };
37
+ /**
38
+ * File system paths
39
+ */
40
+ export const PATHS = {
41
+ BIN_DIR: path.join(__dirname, 'bin'),
42
+ BIN_PATH: path.join(__dirname, 'bin', PLATFORM.BIN_NAME),
43
+ };
44
+ /**
45
+ * Log patterns for filtering cloudflared output
46
+ */
47
+ export const LOG_PATTERNS = SHARED_LOG_PATTERNS;
48
+ /**
49
+ * Network warning configuration
50
+ */
51
+ export const NETWORK_CONFIG = {
52
+ WARNING_THRESHOLD: NETWORK_WARNING.THRESHOLD,
53
+ WARNING_COOLDOWN: NETWORK_WARNING.COOLDOWN,
54
+ };
55
+ /**
56
+ * Tunnel timeout in milliseconds
57
+ */
58
+ export const TUNNEL_TIMEOUT_MS = CONFIG.TUNNEL_TIMEOUT_HOURS * 60 * 60 * 1000;
59
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,IAAI,mBAAmB,EACnC,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAO/C,MAAM,WAAW,GAAgB,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE5D;;GAEG;AACH,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACvC,CAAC;IACD,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAc;IAC/B,YAAY,EAAE,WAAW,CAAC,IAAI;IAC9B,eAAe,EAAE,WAAW,CAAC,OAAO;IACpC,WAAW,EAAE,aAAa,EAAE;IAC5B,YAAY;IACZ,gBAAgB;IAChB,oBAAoB;IACpB,oBAAoB;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAmB;IACtC,UAAU,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;IACxC,QAAQ,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,aAAa;CAC3E,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAgB;IAChC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;IACpC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC;CACzD,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAgB,mBAAmB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,iBAAiB,EAAE,eAAe,CAAC,SAAS;IAC5C,gBAAgB,EAAE,eAAe,CAAC,QAAQ;CAC3C,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared constants used across the application
3
+ */
4
+ /**
5
+ * Default backend API URL
6
+ */
7
+ export declare const DEFAULT_BACKEND_URL = "https://api.nport.link";
8
+ /**
9
+ * Default port if not specified
10
+ */
11
+ export declare const DEFAULT_PORT = 8080;
12
+ /**
13
+ * Prefix for random subdomains
14
+ */
15
+ export declare const SUBDOMAIN_PREFIX = "user-";
16
+ /**
17
+ * Auto-cleanup timeout in hours
18
+ */
19
+ export declare const TUNNEL_TIMEOUT_HOURS = 4;
20
+ /**
21
+ * Timeout for npm version check in milliseconds
22
+ */
23
+ export declare const UPDATE_CHECK_TIMEOUT = 3000;
24
+ /**
25
+ * Analytics request timeout in milliseconds
26
+ */
27
+ export declare const ANALYTICS_TIMEOUT = 2000;
28
+ /**
29
+ * Network warning configuration
30
+ */
31
+ export declare const NETWORK_WARNING: {
32
+ /** Number of errors before showing warning */
33
+ readonly THRESHOLD: 5;
34
+ /** Minimum ms between warnings */
35
+ readonly COOLDOWN: 30000;
36
+ };
37
+ /**
38
+ * Log patterns for filtering cloudflared output
39
+ */
40
+ export declare const LOG_PATTERNS: {
41
+ readonly SUCCESS: readonly ["Registered tunnel connection"];
42
+ readonly ERROR: readonly ["ERR", "error"];
43
+ readonly NETWORK_WARNING: readonly ["failed to accept QUIC stream", "failed to dial to edge with quic", "failed to accept incoming stream requests", "Failed to dial a quic connection", "timeout: no recent network activity", "failed to dial to edge", "quic:"];
44
+ readonly IGNORE: readonly ["Cannot determine default origin certificate path", "No file cert.pem", "origincert option", "TUNNEL_ORIGIN_CERT", "context canceled", "failed to run the datagram handler", "failed to serve tunnel connection", "Connection terminated", "no more connections active and exiting", "Serve tunnel error", "accept stream listener encountered a failure", "Retrying connection", "icmp router terminated", "use of closed network connection", "Application error 0x0"];
45
+ };
46
+ /**
47
+ * Available language codes
48
+ */
49
+ export declare const AVAILABLE_LANGUAGES: readonly ["en", "vi"];
50
+ /**
51
+ * GitHub repository URL
52
+ */
53
+ export declare const GITHUB_URL = "https://github.com/tuanngocptn/nport";
54
+ /**
55
+ * Website URL
56
+ */
57
+ export declare const WEBSITE_URL = "https://nport.link";
58
+ /**
59
+ * Buy Me a Coffee URL
60
+ */
61
+ export declare const COFFEE_URL = "https://buymeacoffee.com/tuanngocptn";
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Shared constants used across the application
3
+ */
4
+ /**
5
+ * Default backend API URL
6
+ */
7
+ export const DEFAULT_BACKEND_URL = 'https://api.nport.link';
8
+ /**
9
+ * Default port if not specified
10
+ */
11
+ export const DEFAULT_PORT = 8080;
12
+ /**
13
+ * Prefix for random subdomains
14
+ */
15
+ export const SUBDOMAIN_PREFIX = 'user-';
16
+ /**
17
+ * Auto-cleanup timeout in hours
18
+ */
19
+ export const TUNNEL_TIMEOUT_HOURS = 4;
20
+ /**
21
+ * Timeout for npm version check in milliseconds
22
+ */
23
+ export const UPDATE_CHECK_TIMEOUT = 3000;
24
+ /**
25
+ * Analytics request timeout in milliseconds
26
+ */
27
+ export const ANALYTICS_TIMEOUT = 2000;
28
+ /**
29
+ * Network warning configuration
30
+ */
31
+ export const NETWORK_WARNING = {
32
+ /** Number of errors before showing warning */
33
+ THRESHOLD: 5,
34
+ /** Minimum ms between warnings */
35
+ COOLDOWN: 30000,
36
+ };
37
+ /**
38
+ * Log patterns for filtering cloudflared output
39
+ */
40
+ export const LOG_PATTERNS = {
41
+ SUCCESS: ['Registered tunnel connection'],
42
+ ERROR: ['ERR', 'error'],
43
+ NETWORK_WARNING: [
44
+ 'failed to accept QUIC stream',
45
+ 'failed to dial to edge with quic',
46
+ 'failed to accept incoming stream requests',
47
+ 'Failed to dial a quic connection',
48
+ 'timeout: no recent network activity',
49
+ 'failed to dial to edge',
50
+ 'quic:',
51
+ ],
52
+ IGNORE: [
53
+ 'Cannot determine default origin certificate path',
54
+ 'No file cert.pem',
55
+ 'origincert option',
56
+ 'TUNNEL_ORIGIN_CERT',
57
+ 'context canceled',
58
+ 'failed to run the datagram handler',
59
+ 'failed to serve tunnel connection',
60
+ 'Connection terminated',
61
+ 'no more connections active and exiting',
62
+ 'Serve tunnel error',
63
+ 'accept stream listener encountered a failure',
64
+ 'Retrying connection',
65
+ 'icmp router terminated',
66
+ 'use of closed network connection',
67
+ 'Application error 0x0',
68
+ ],
69
+ };
70
+ /**
71
+ * Available language codes
72
+ */
73
+ export const AVAILABLE_LANGUAGES = ['en', 'vi'];
74
+ /**
75
+ * GitHub repository URL
76
+ */
77
+ export const GITHUB_URL = 'https://github.com/tuanngocptn/nport';
78
+ /**
79
+ * Website URL
80
+ */
81
+ export const WEBSITE_URL = 'https://nport.link';
82
+ /**
83
+ * Buy Me a Coffee URL
84
+ */
85
+ export const COFFEE_URL = 'https://buymeacoffee.com/tuanngocptn';
86
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,wBAAwB,CAAC;AAE5D;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAExC;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,8CAA8C;IAC9C,SAAS,EAAE,CAAC;IACZ,kCAAkC;IAClC,QAAQ,EAAE,KAAK;CACP,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,CAAC,8BAA8B,CAAC;IACzC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE;QACf,8BAA8B;QAC9B,kCAAkC;QAClC,2CAA2C;QAC3C,kCAAkC;QAClC,qCAAqC;QACrC,wBAAwB;QACxB,OAAO;KACR;IACD,MAAM,EAAE;QACN,kDAAkD;QAClD,kBAAkB;QAClB,mBAAmB;QACnB,oBAAoB;QACpB,kBAAkB;QAClB,oCAAoC;QACpC,mCAAmC;QACnC,uBAAuB;QACvB,wCAAwC;QACxC,oBAAoB;QACpB,8CAA8C;QAC9C,qBAAqB;QACrB,wBAAwB;QACxB,kCAAkC;QAClC,uBAAuB;KACxB;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,IAAI,CAAU,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAEjE;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,sCAAsC,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NPort - Free & Open Source ngrok Alternative
4
+ *
5
+ * Main entry point for the NPort CLI application.
6
+ */
7
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * NPort - Free & Open Source ngrok Alternative
4
+ *
5
+ * Main entry point for the NPort CLI application.
6
+ */
7
+ import ora from 'ora';
8
+ import chalk from 'chalk';
9
+ import { ArgumentParser } from './args.js';
10
+ import { TunnelOrchestrator } from './tunnel.js';
11
+ import { VersionManager } from './version.js';
12
+ import { UI } from './ui.js';
13
+ import { CONFIG } from './config.js';
14
+ import { lang } from './lang.js';
15
+ import { configManager } from './config-manager.js';
16
+ /**
17
+ * Displays version information with update check.
18
+ */
19
+ async function displayVersion() {
20
+ const spinner = ora(lang.t('checkingUpdates')).start();
21
+ const updateInfo = await VersionManager.checkForUpdates();
22
+ spinner.stop();
23
+ UI.displayVersion(CONFIG.CURRENT_VERSION, updateInfo);
24
+ }
25
+ /**
26
+ * Handles the --set-backend command.
27
+ */
28
+ function handleSetBackend(value) {
29
+ if (value === 'clear') {
30
+ configManager.setBackendUrl(null);
31
+ console.log(chalk.green('✔ Backend URL cleared. Using default backend.'));
32
+ console.log(chalk.gray(' Default: https://api.nport.link\n'));
33
+ }
34
+ else {
35
+ configManager.setBackendUrl(value);
36
+ console.log(chalk.green('✔ Backend URL saved successfully!'));
37
+ console.log(chalk.cyan(` Backend: ${value}`));
38
+ console.log(chalk.gray('\n This backend will be used for all future sessions.'));
39
+ console.log(chalk.gray(' To clear: nport --set-backend\n'));
40
+ }
41
+ const savedUrl = configManager.getBackendUrl();
42
+ if (savedUrl) {
43
+ console.log(chalk.white('Current configuration:'));
44
+ console.log(chalk.cyan(` Saved backend: ${savedUrl}`));
45
+ }
46
+ }
47
+ /**
48
+ * Main application entry point.
49
+ */
50
+ async function main() {
51
+ try {
52
+ const args = process.argv.slice(2);
53
+ const parsedArgs = ArgumentParser.parse(args);
54
+ await lang.initialize(parsedArgs.language);
55
+ if (args.includes('-v') || args.includes('--version')) {
56
+ await displayVersion();
57
+ process.exit(0);
58
+ }
59
+ if (parsedArgs.setBackend) {
60
+ handleSetBackend(parsedArgs.setBackend);
61
+ process.exit(0);
62
+ }
63
+ if (parsedArgs.language === 'prompt' &&
64
+ (args.includes('--language') || args.includes('--lang') || args.includes('-l'))) {
65
+ process.exit(0);
66
+ }
67
+ let backendUrl = parsedArgs.backendUrl;
68
+ if (!backendUrl) {
69
+ const savedBackend = configManager.getBackendUrl();
70
+ if (savedBackend) {
71
+ backendUrl = savedBackend;
72
+ }
73
+ }
74
+ const config = {
75
+ port: parsedArgs.port,
76
+ subdomain: parsedArgs.subdomain,
77
+ backendUrl,
78
+ language: parsedArgs.language,
79
+ };
80
+ await TunnelOrchestrator.start(config);
81
+ }
82
+ catch (error) {
83
+ console.error(`Fatal Error: ${error.message}`);
84
+ process.exit(1);
85
+ }
86
+ }
87
+ // Register cleanup handlers
88
+ process.on('SIGINT', () => TunnelOrchestrator.cleanup());
89
+ process.on('SIGTERM', () => TunnelOrchestrator.cleanup());
90
+ // Start application
91
+ main();
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/lang.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ import type { LanguageCode, TranslationKeys, TranslationVariables } from './types/index.js';
2
+ /**
3
+ * Language Manager
4
+ */
5
+ declare class LanguageManager {
6
+ private currentLanguage;
7
+ private readonly availableLanguages;
8
+ /**
9
+ * Gets a translated string with variable substitution.
10
+ */
11
+ t(key: keyof TranslationKeys, vars?: TranslationVariables): string;
12
+ /**
13
+ * Loads saved language preference.
14
+ */
15
+ private loadLanguagePreference;
16
+ /**
17
+ * Saves language preference.
18
+ */
19
+ private saveLanguagePreference;
20
+ /**
21
+ * Sets the current language.
22
+ */
23
+ setLanguage(lang: string): boolean;
24
+ /**
25
+ * Gets the current language code.
26
+ */
27
+ getLanguage(): LanguageCode;
28
+ /**
29
+ * Prompts user to select a language.
30
+ */
31
+ promptLanguageSelection(): Promise<LanguageCode>;
32
+ /**
33
+ * Initializes the language system.
34
+ */
35
+ initialize(cliLanguage?: string | null): Promise<LanguageCode>;
36
+ }
37
+ export declare const lang: LanguageManager;
38
+ export {};