padavan 1.0.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,98 +1,125 @@
1
- Router management with Padavan firmware
1
+ # padavan
2
2
 
3
+ [[RU]](./docs/ru/README.md) | [EN]
3
4
 
4
- ## Install
5
+ A Node.js library for managing routers running **Padavan** firmware.
5
6
 
6
- ``` shell
7
- npm install padavan
8
- ```
7
+ It interacts with the router via its **Web Interface (HTTP)**, providing
8
+ programmatic access to configuration, diagnostics, and firmware management
9
+ functions.
9
10
 
11
+ ## Migration
10
12
 
11
- ## Usage
12
-
13
- ```javascript
14
- import Padavan from 'padavan';
15
- const client = new Padavan({
16
- repo, branch, token, // GITHUB
17
- host, username, password // Router
18
- });
19
- ```
13
+ Upgrading from v1? Check the [Migration Guide](../../docs/MIGRATION.md) for
14
+ details on breaking changes (move from SSH to HTTP, new constructor) and removed
15
+ features.
20
16
 
17
+ ## Installation
21
18
 
22
- ## API
23
-
24
- ### Get current status
25
- ```javascript
26
- await client.getStatus();
27
- // { lavg, uptime, ram, swap, cpu, wifi2, wifi5 }
19
+ ```bash
20
+ npm install padavan
28
21
  ```
29
22
 
30
- ### Get traffic history
31
- ```javascript
32
- await client.getHistory();
33
- // { daily_history, monthly_history }
34
- ```
23
+ ## Usage
35
24
 
36
- ### Get logs
37
25
  ```javascript
38
- await client.getLog();
39
- ```
26
+ import Padavan from 'padavan';
40
27
 
41
- ### Get device list
42
- ```javascript
43
- await client.getDevices();
44
- // [{ hostname, ip, mac, rssi }]
45
- ```
28
+ const client = new Padavan({
29
+ credentials: {
30
+ host: '192.168.1.1',
31
+ username: 'admin',
32
+ password: 'password'
33
+ },
34
+ logLevel: 'error'
35
+ });
46
36
 
47
- ### Get parameters
48
- ```javascript
49
- await client.getParams(); // Object with all parameters
50
- await client.getParams('firmver_sub'); // Only { firmver_sub }
51
- await client.getParams([ 'firmver_sub', 'ip6_service' ]); // { firmver_sub, ip6_service }
37
+ // Get system status
38
+ const status = await client.getStatus();
39
+ console.log(`Uptime: ${status.uptime}`);
52
40
  ```
53
41
 
54
- ### Set parameters
55
- ```javascript
56
- await client.setParams({
57
- sid_list: 'IP6Connection;',
58
- ip6_service: '6in4'
59
- }); // Enable ipv6
60
- await client.setParams({
61
- ip6_service: ''
62
- }); // Disable ipv6
63
- ```
42
+ ## Configuration
64
43
 
65
- ### Start SpeedTest on the device
66
- ```javascript
67
- await client.startSpeedTest();
68
- // { networkDownloadSpeedMbps, networkUploadSpeedMbps }
69
- ```
44
+ The constructor accepts a config object with the following properties:
70
45
 
71
- ### Start firmware build in the repository
72
- ```javascript
73
- await client.startBuild();
74
- ```
46
+ | Property | Description |
47
+ | --- | --- |
48
+ | `credentials` | Object containing connection details. |
49
+ | `logLevel` | Logging level: `'none'`, `'error'`, `'info'`, `'debug'`. |
75
50
 
76
- ### Get the firmware changelog
77
- ```javascript
78
- await client.getChangelog();
79
- await client.getChangelog(from_id, to_id);
80
- // { from_id, to_id, data: [] }
81
- ```
51
+ ### Credentials Object
82
52
 
83
- ### Start firmware upgrade
84
- ```javascript
85
- await client.startUpgrade();
86
- ```
53
+ | Property | Description |
54
+ | --- | --- |
55
+ | `host` | Router IP address or hostname. |
56
+ | `username` | Web interface username. |
57
+ | `password` | Web interface password. |
58
+ | `repo` | GitHub `owner/repo` for firmware updates. |
59
+ | `branch` | GitHub branch (e.g., `main`). |
60
+ | `token` | GitHub PAT for accessing Actions/Artifacts. |
87
61
 
88
- ### Reboot
89
- ```javascript
90
- await client.startReboot();
91
- ```
62
+ ## API
92
63
 
93
- ### Find repositories with firmware for the device
94
- ```javascript
95
- await client.find();
96
- await client.find(productid);
97
- // [{ repo, branch, active, created_at, name }]
98
- ```
64
+ ### System & Diagnostics
65
+
66
+ - **`getStatus()`**
67
+ Returns CPU load, RAM usage, uptime, and basic Wi-Fi status.
68
+ - **`getLog()`**
69
+ Fetches the complete system log.
70
+ - **`exec(command)`**
71
+ Executes a system command via the web console emulator (`SystemCmd`).
72
+ *Returns:* Command output (stdout + stderr).
73
+ - **`startReboot()`**
74
+ Reboots the router via HTTP command.
75
+
76
+ ### Network & Clients
77
+
78
+ - **`getDevices()`**
79
+ Returns a list of connected clients from the ARP table and Wi-Fi driver.
80
+ *Properties:* `mac`, `ip`, `hostname`, `type` (eth, wifi, 2.4GHz, 5GHz),
81
+ `rssi`.
82
+ - **`getHistory()`**
83
+ Returns traffic statistics.
84
+ *Structure:* `{ daily: [...], monthly: [...] }`.
85
+
86
+ ### Wi-Fi Tools
87
+
88
+ - **`startScan(band)`**
89
+ Performs a Site Survey (scan).
90
+ *Band:* `'2.4'` or `'5'`.
91
+ - **`getBestChannel(band)`**
92
+ **Wi-Fi Doctor**: Scans the environment, calculates interference scores, and
93
+ recommends the optimal channel for your router.
94
+
95
+ ### NVRAM & Settings
96
+
97
+ - **`getParams(keys?, page?)`**
98
+ Returns NVRAM variables.
99
+ *Arguments:*
100
+ - `keys`: Specific key string or array of keys. If omitted, returns all.
101
+ - `page`: If provided, parses input fields from a specific ASP page HTML instead
102
+ of using `nvram show`.
103
+ - **`setParams(params, options?)`**
104
+ Sets NVRAM variables.
105
+ *Options:* `action_mode` (e.g., `' Apply '`), `sid_list` (Service IDs to
106
+ restart), `group_id`, `current_page`.
107
+
108
+ ### Firmware Management
109
+
110
+ Requires GitHub credentials (`repo`, `branch`, `token`).
111
+
112
+ - **`findFirmware(model?)`**
113
+ Searches for firmware artifacts in the configured repository network (looks
114
+ into forks).
115
+ - **`getChangelog()`**
116
+ Compares the current router version with the latest artifact and returns a list
117
+ of commits.
118
+ - **`startBuild()`**
119
+ Triggers a GitHub Actions workflow to build new firmware.
120
+ - **`startUpgrade()`**
121
+ Downloads the latest artifact, uploads it to the router, and flashes it.
122
+
123
+ ## CLI
124
+
125
+ This package includes a CLI tool. See [CLI Documentation](docs/en-US/CLI.md).
package/bin/cli.js ADDED
@@ -0,0 +1,273 @@
1
+ #!/usr/bin/env node
2
+
3
+ import yargs from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import Padavan from '../src/index.js';
6
+ import { formatBytes, formatUptime } from '../src/utils/formatting.js';
7
+ import { DEFAULT_HTTP_CONFIG, DEFAULT_FIRMWARE_REPO, ACTION_MODE, SERVICE_ID, GROUP_ID } from '../src/constants.js';
8
+ /** @import { ActionMode, ServiceId, GroupId } from '../src/constants.js' */
9
+ /** @import { ArgumentsCamelCase } from 'yargs' */
10
+ /** @import { Device, WifiNetwork, ChannelAnalysis } from '../src/index.js' */
11
+
12
+ /**
13
+ * @typedef {Object} CommonArgs
14
+ * @property {string} host
15
+ * @property {number} port
16
+ * @property {string} user
17
+ * @property {string} password
18
+ * @property {boolean} verbose
19
+ * @property {boolean} json
20
+ */
21
+
22
+ /**
23
+ * @typedef {Object} FirmwareArgs
24
+ * @property {string} action
25
+ * @property {string} [repo]
26
+ * @property {string} [branch]
27
+ * @property {string} [token]
28
+ * @property {string} [model]
29
+ */
30
+
31
+ const logInfo = (/** @type {string} */ msg) => console.error(msg);
32
+
33
+ /**
34
+ * @param {CommonArgs} argv
35
+ * @param {any} data
36
+ * @param {(item: any) => any} [tableTransform]
37
+ */
38
+ const printOutput = (argv, data, tableTransform = null) => {
39
+ if (argv.json)
40
+ return console.log(JSON.stringify(data, null, 2));
41
+ let output = data;
42
+ if (tableTransform)
43
+ output = Array.isArray(data) ? data.map(tableTransform) : tableTransform(data);
44
+ if (Array.isArray(output))
45
+ return output.length ? console.table(output) : logInfo('No results found.');
46
+ if (output && typeof output === 'object')
47
+ return Object.keys(output).length ? console.table(output) : logInfo('No results found.');
48
+ console.log(output);
49
+ };
50
+
51
+ const getClient = (/** @type {ArgumentsCamelCase<CommonArgs & Partial<FirmwareArgs>>} */ argv) => {
52
+ const logLevel = argv.verbose ? 'debug' : 'none';
53
+ return new Padavan({ credentials: argv, logLevel });
54
+ };
55
+
56
+ const args = hideBin(process.argv);
57
+ const cli = yargs(args)
58
+ .env('PADAVAN')
59
+ .option('host', { type: 'string', describe: 'Router IP', default: DEFAULT_HTTP_CONFIG.host })
60
+ .option('port', { type: 'number', describe: 'Port', default: DEFAULT_HTTP_CONFIG.port })
61
+ .option('user', { type: 'string', describe: 'Username', default: DEFAULT_HTTP_CONFIG.username })
62
+ .option('password', { type: 'string', describe: 'Password', default: DEFAULT_HTTP_CONFIG.password })
63
+ .option('json', { type: 'boolean', describe: 'Output result as JSON', default: false })
64
+ .option('verbose', { type: 'boolean', describe: 'Show debug logs' });
65
+
66
+ // --- STATUS & INFO ---
67
+
68
+ cli.command('status', 'Get system status', {}, async (/** @type {ArgumentsCamelCase<CommonArgs>} */ argv) => {
69
+ const client = getClient(argv);
70
+ const status = await client.getStatus();
71
+ printOutput(argv, status, (s) => ({
72
+ 'Uptime': formatUptime(s.uptime),
73
+ 'Load Avg': s.lavg,
74
+ 'RAM Free': formatBytes(s.ram.free * 1024),
75
+ 'RAM Used': formatBytes(s.ram.used * 1024),
76
+ 'RAM Total': formatBytes(s.ram.total * 1024)
77
+ }));
78
+ });
79
+
80
+ cli.command('devices', 'List connected devices', {}, async (/** @type {ArgumentsCamelCase<CommonArgs>} */ argv) => {
81
+ const client = getClient(argv);
82
+ const devices = await client.getDevices();
83
+ printOutput(argv, devices, (/** @type {Device} */ d) => ({
84
+ MAC: d.mac,
85
+ IP: d.ip,
86
+ HostName: d.hostname,
87
+ Type: d.type,
88
+ RSSI: d.rssi ? d.rssi + '%' : null
89
+ }));
90
+ });
91
+
92
+ cli.command('log', 'Get system log', {}, async (/** @type {ArgumentsCamelCase<CommonArgs>} */ argv) => {
93
+ const client = getClient(argv);
94
+ const log = await client.getLog();
95
+ console.log(log);
96
+ });
97
+
98
+ cli.command('traffic', 'Get traffic history', {}, async (/** @type {ArgumentsCamelCase<CommonArgs>} */ argv) => {
99
+ const client = getClient(argv);
100
+ const history = await client.getHistory();
101
+ if (argv.json) {
102
+ printOutput(argv, history);
103
+ return;
104
+ }
105
+ const trafficTable = (/** @type {any} */ item) => ({
106
+ Date: item.dateStr,
107
+ Download: formatBytes(item.download * 1024),
108
+ Upload: formatBytes(item.upload * 1024),
109
+ Total: formatBytes((item.download + item.upload) * 1024)
110
+ });
111
+ logInfo('Daily History (Last 10):');
112
+ console.table(history.daily.slice().reverse().slice(0, 10).map(trafficTable));
113
+ logInfo('Monthly History (Last 10):');
114
+ console.table(history.monthly.slice().reverse().slice(0, 10).map(trafficTable));
115
+ });
116
+
117
+ // --- WIFI DOCTOR ---
118
+
119
+ cli.command('scan [band]', 'Scan Wi-Fi networks', (yargs) => {
120
+ return yargs.positional('band', { type: 'string', choices: ['2.4', '5'], default: '2.4' });
121
+ }, async (/** @type {ArgumentsCamelCase<CommonArgs & {band: '2.4'|'5'}>} */ argv) => {
122
+ const client = getClient(argv);
123
+ logInfo(`Scanning ${argv.band}GHz networks...`);
124
+ const networks = await client.startScan(argv.band);
125
+ printOutput(argv, networks, (/** @type {WifiNetwork} */ n) => ({
126
+ SSID: n.ssid,
127
+ Channel: n.channel,
128
+ Quality: n.quality + '%',
129
+ BSSID: n.bssid
130
+ }));
131
+ });
132
+
133
+ cli.command('doctor [band]', 'Analyze Wi-Fi environment and recommend channel', (yargs) => {
134
+ return yargs.positional('band', { type: 'string', choices: ['2.4', '5'], default: '2.4' });
135
+ }, async (/** @type {ArgumentsCamelCase<CommonArgs & {band: '2.4'|'5'}>} */ argv) => {
136
+ const client = getClient(argv);
137
+ logInfo(`Scanning and analyzing ${argv.band}GHz spectrum...`);
138
+ const result = await client.getBestChannel(argv.band);
139
+ printOutput(argv, result, (/** @type {ChannelAnalysis} */ r) => ({
140
+ 'Current': r.currentChannel,
141
+ 'Best': r.bestChannel,
142
+ 'Optimal?': r.isCurrentOptimal ? 'Yes' : 'No',
143
+ 'Reason': r.reason
144
+ }));
145
+ });
146
+
147
+ // --- PARAMS (NVRAM) ---
148
+
149
+ cli.command('params [keys..]', 'Get parameters (NVRAM or Page inputs)', (yargs) => {
150
+ return yargs
151
+ .option('page', { type: 'string', describe: 'Target ASP page to parse inputs from' });
152
+ }, async (/** @type {ArgumentsCamelCase<CommonArgs & {keys?: string[], page?: string}>} */ argv) => {
153
+ const client = getClient(argv);
154
+ const params = await client.getParams(argv.keys, argv.page);
155
+ printOutput(argv, params);
156
+ });
157
+
158
+ cli.command('set <pairs..>', 'Set parameters (key=value)', (yargs) => {
159
+ return yargs
160
+ .option('page', { type: 'string', describe: 'Current page (for auto-SID detection)' })
161
+ .option('sid', { type: 'array', describe: 'Service ID list', choices: SERVICE_ID })
162
+ .option('group', { type: 'string', describe: 'Group ID (required for Add/Del actions)', choices: GROUP_ID })
163
+ .option('script', { type: 'string', describe: 'Action script' })
164
+ .option('action', {
165
+ type: 'string',
166
+ describe: 'Action mode',
167
+ default: 'Apply',
168
+ coerce: (arg) => {
169
+ const clean = arg.trim();
170
+ const match = ACTION_MODE.map(m => m.trim()).find(m => m.toLowerCase() === clean.toLowerCase());
171
+ return match || arg;
172
+ },
173
+ choices: ACTION_MODE.map(m => m.trim())
174
+ })
175
+ .example('$0 set rt_ssid=MyWifi --page "Advanced_WAdvanced_Content.asp"', 'Apply settings via Web UI')
176
+ .example('$0 set "rt_ACLList=AA:BB:CC:DD:EE:FF" --action Add --group rt_ACLList', 'Add MAC to filter');
177
+ }, async (/** @type {ArgumentsCamelCase<CommonArgs & {pairs: string[], sid?: string|ServiceId[], page?: string, action?: ActionMode, group?: GroupId, script?: string}>} */ argv) => {
178
+ const client = getClient(argv);
179
+ const /** @type {Record<string, string>} */ params = {};
180
+ argv.pairs.forEach(p => {
181
+ const [k, ...v] = p.split('=');
182
+ if (k)
183
+ params[k] = v.join('=');
184
+ });
185
+ const action_mode = ACTION_MODE.find(m => m.trim() === argv.action) || argv.action;
186
+ await client.setParams(params, {
187
+ action_mode,
188
+ action_script: argv.script,
189
+ sid_list: argv.sid,
190
+ group_id: argv.group,
191
+ current_page: argv.page
192
+ });
193
+ logInfo('Settings applied successfully.');
194
+ });
195
+
196
+ // --- FIRMWARE ---
197
+
198
+ cli.command('firmware <action>', 'Manage firmware', (yargs) => {
199
+ return yargs
200
+ .positional('action', { choices: ['changelog', 'build', 'upgrade', 'search'] })
201
+ .option('repo', { type: 'string', describe: 'GitHub Owner/Repo', default: DEFAULT_FIRMWARE_REPO })
202
+ .option('branch', { type: 'string', describe: 'Branch name' })
203
+ .option('token', { type: 'string', describe: 'GitHub Token' })
204
+ .option('model', { type: 'string', describe: 'Model filter for search' });
205
+ }, async (/** @type {ArgumentsCamelCase<CommonArgs & FirmwareArgs>} */ argv) => {
206
+ if (argv.action !== 'search' && !argv.repo)
207
+ throw new Error(`--repo is required for ${argv.action}`);
208
+
209
+ const client = getClient(argv);
210
+ switch (argv.action) {
211
+ case 'search': {
212
+ logInfo(`Searching firmware (Source: ${argv.repo}, Model: ${argv.model || 'Auto'})...`);
213
+ const results = await client.findFirmware(argv.model);
214
+ printOutput(argv, results, (r) => ({
215
+ 'Date': new Date(r.created_at).toLocaleDateString(),
216
+ 'Repo': r.repo,
217
+ 'Branch': r.branch,
218
+ 'Firmware': r.name,
219
+ 'Size': formatBytes(r.size)
220
+ }));
221
+ break;
222
+ }
223
+ case 'build': {
224
+ logInfo(`Triggering build in ${argv.repo}...`);
225
+ await client.startBuild();
226
+ logInfo('Build started! Check GitHub Actions tab.');
227
+ break;
228
+ }
229
+ case 'changelog': {
230
+ logInfo('Fetching changelog...');
231
+ const log = await client.getChangelog();
232
+ logInfo(`\nChanges from ${log.from} to ${log.to}:`);
233
+ if (log.messages.length === 0)
234
+ logInfo('No changes (versions are identical).');
235
+ else
236
+ log.messages.forEach(msg => console.log(`- ${msg}`));
237
+ break;
238
+ }
239
+ case 'upgrade': {
240
+ logInfo('WARNING: This will download the latest artifact and flash your router.');
241
+ logInfo('Do not turn off power!');
242
+ await client.startUpgrade();
243
+ logInfo('Upgrade process started. Router is rebooting...');
244
+ break;
245
+ }
246
+ }
247
+ });
248
+
249
+ // --- SYSTEM ---
250
+
251
+ cli.command('reboot', 'Reboot the router', {}, async (/** @type {ArgumentsCamelCase<CommonArgs>} */ argv) => {
252
+ const client = getClient(argv);
253
+ logInfo('Sending reboot command...');
254
+ await client.startReboot();
255
+ logInfo('Reboot command sent.');
256
+ });
257
+
258
+ cli.fail((msg, err, yargs) => {
259
+ if (err)
260
+ console.error(err.message);
261
+ else if (msg && !(args.length === 1 && args[0] === 'firmware'))
262
+ console.error(msg);
263
+ else
264
+ yargs.showHelp();
265
+ process.exit(1);
266
+ });
267
+
268
+ cli
269
+ .demandCommand(1, '')
270
+ .recommendCommands()
271
+ .help().alias('h', 'help')
272
+ .version().alias('v', 'version')
273
+ .parse();
package/package.json CHANGED
@@ -1,28 +1,45 @@
1
1
  {
2
2
  "name": "padavan",
3
- "version": "1.0.1",
4
- "description": "Router management with Padavan firmware",
5
- "main": "main.mjs",
3
+ "version": "2.0.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "The core library for interacting with routers running Padavan firmware. Provides a programmatic API for local control via HTTP.",
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./*": "./src/*"
10
+ },
11
+ "bin": {
12
+ "padavan": "./bin/cli.js"
13
+ },
14
+ "scripts": {
15
+ "test": "tsc -p ./jsconfig.json"
16
+ },
6
17
  "files": [
7
- "services/",
8
- "main.mjs"
18
+ "./bin/",
19
+ "./src/*.js"
9
20
  ],
21
+ "dependencies": {
22
+ "jszip": "^3.10.1",
23
+ "yargs": "^18.0.0"
24
+ },
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "license": "MIT",
10
29
  "repository": {
11
30
  "type": "git",
12
- "url": "git+https://github.com/alex2844/node-padavan.git"
31
+ "url": "git+https://github.com/alex2844/node-padavan.git",
32
+ "directory": "packages/node"
13
33
  },
14
34
  "keywords": [
35
+ "router",
36
+ "padavan",
15
37
  "nodejs",
16
38
  "iot",
17
- "smart home",
18
- "router",
19
- "padavan"
20
- ],
21
- "author": "Alex Smith",
22
- "license": "MIT",
23
- "dependencies": {
24
- "ini": "^4.1.3",
25
- "jszip": "^3.10.1",
26
- "ssh2": "^1.15.0"
27
- }
28
- }
39
+ "smarthome",
40
+ "home-automation",
41
+ "javascript",
42
+ "library",
43
+ "api"
44
+ ]
45
+ }
@@ -0,0 +1,98 @@
1
+ /** Идентификатор библиотеки для debuglog. */
2
+ export const LIB_ID = 'padavan';
3
+
4
+ /**
5
+ * Уровни логирования.
6
+ * @enum {number}
7
+ */
8
+ export const LOG_LEVELS = /** @type {const} */ ({
9
+ none: 0,
10
+ error: 1,
11
+ warn: 2,
12
+ info: 3,
13
+ debug: 4
14
+ });
15
+
16
+ /** Уровень логирования по умолчанию. */
17
+ export const DEFAULT_LOG_LEVEL = 'none';
18
+
19
+ /** Репозиторий с прошивками по умолчанию. */
20
+ export const DEFAULT_FIRMWARE_REPO = 'alex2844/node-padavan';
21
+
22
+ /** Конфигурация HTTP клиента по умолчанию. */
23
+ export const DEFAULT_HTTP_CONFIG = {
24
+ host: '192.168.1.1',
25
+ port: 80,
26
+ username: 'admin',
27
+ password: 'admin'
28
+ };
29
+
30
+ /** Время жизни кэша NVRAM в миллисекундах. */
31
+ export const NVRAM_CACHE_TTL = 3_000;
32
+
33
+ /**
34
+ * Режимы действия для apply.cgi.
35
+ * Обратите внимание: большинство команд требуют пробелы по краям.
36
+ * @typedef {(typeof ACTION_MODE)[number]} ActionMode
37
+ */
38
+ export const ACTION_MODE = /** @type {const} */ ([
39
+ ' Apply ', ' Restart ', ' Reboot ', ' Shutdown ',
40
+ ' Add ', ' Del ', ' ClearLog ', ' SystemCmd ',
41
+ ' CommitFlash ', ' RestoreNVRAM ', ' RestoreStorage ', ' FreeMemory ',
42
+ ' NTPSyncNow ', ' CreateCertHTTPS ', ' CheckCertHTTPS ',
43
+ ' CreateCertOVPNS ', ' ExportConfOVPNC ', ' ExportWGConf ',
44
+ ' wg_action ', 'Update'
45
+ ]);
46
+
47
+ /**
48
+ * Идентификаторы сервисов (Service ID).
49
+ * Используются для уведомления демонов (rc) о необходимости перечитать конфиги.
50
+ * @typedef {(typeof SERVICE_ID)[number]} ServiceId
51
+ */
52
+ export const SERVICE_ID = /** @type {const} */ ([
53
+ 'General', 'LANHostConfig', 'IPConnection', 'PPPConnection', 'FirewallConfig', 'RouterConfig',
54
+ 'WLANConfig11a', 'WLANConfig11b', 'WLANAuthentication11a', 'WLANAuthentication11b',
55
+ 'Storage', 'IP6Connection', 'Layer3Forwarding'
56
+ ]);
57
+
58
+ /**
59
+ * Идентификаторы групп для списков (NVRAM Lists).
60
+ * Ообязателен, если action_mode=' Add ' или ' Del '.
61
+ * @typedef {(typeof GROUP_ID)[number]} GroupId
62
+ */
63
+ export const GROUP_ID = /** @type {const} */ ([
64
+ 'ManualDHCPList', 'VSList', 'GWStatic', 'UrlList', 'MFList',
65
+ 'ACLList', 'rt_ACLList', 'RBRList', 'rt_RBRList',
66
+ 'LWFilterList', 'VPNSACLList'
67
+ ]);
68
+
69
+ /** Системные команды роутера. */
70
+ export const COMMANDS = {
71
+ NVRAM_SHOW: 'nvram showall'
72
+ };
73
+
74
+ /** Список используемых страниц веб-интерфейса. */
75
+ export const PAGES = {
76
+ /** Основной список клиентов (ARP + Wireless) */
77
+ CLIENTS: 'device-map/clients.asp',
78
+ /** Логи драйвера 2.4GHz */
79
+ WIFI_2G: 'Main_WStatus2g_Content.asp',
80
+ /** Логи драйвера 5GHz */
81
+ WIFI_5G: 'Main_WStatus_Content.asp',
82
+ /** Инициация сканирования 2.4GHz */
83
+ SCAN_2G: 'wds_aplist_2g.asp',
84
+ /** Инициация сканирования 5GHz */
85
+ SCAN_5G: 'wds_aplist.asp',
86
+ /** Текущий статус системы (JSON-like) */
87
+ STATUS: 'system_status_data.asp',
88
+ /** История трафика */
89
+ TRAFFIC: 'Main_TrafficMonitor_daily.asp',
90
+ /** Результат выполнения системной команды */
91
+ CONSOLE_RESPONSE: 'console_response.asp',
92
+ /** Системный журнал */
93
+ SYSLOG: 'Main_LogStatus_Content.asp',
94
+ /** Страница обновления прошивки (POST) */
95
+ UPGRADE: 'upgrade.cgi',
96
+ /** Основная точка входа для применения настроек (POST) */
97
+ APPLY: 'apply.cgi'
98
+ };