@fett/synology-api 0.0.1-beta.4 → 0.0.1-beta.6
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/bin/syno +6 -0
- package/{dist → lib}/cjs/index.js +199 -18
- package/package.json +21 -10
- package/dist/esm/constants.js +0 -5
- package/dist/esm/core.js +0 -111
- package/dist/esm/errorcodes.js +0 -97
- package/dist/esm/helpers.js +0 -80
- package/dist/esm/index.js +0 -4
- package/dist/esm/modules/Api/Auth.js +0 -43
- package/dist/esm/modules/Api/Info.js +0 -26
- package/dist/esm/modules/Api/index.js +0 -2
- package/dist/esm/modules/AudioStation/Song.js +0 -18
- package/dist/esm/modules/AudioStation/index.js +0 -5
- package/dist/esm/modules/FileStation/File.js +0 -0
- package/dist/esm/modules/FileStation/Info.js +0 -20
- package/dist/esm/modules/FileStation/List.js +0 -32
- package/dist/esm/modules/FileStation/index.js +0 -11
- package/dist/esm/modules/index.js +0 -28
- package/dist/esm/types/apiInfo.js +0 -42
- package/dist/esm/types/index.js +0 -2
- package/dist/esm/types/request.js +0 -2
- package/dist/esm/utils.js +0 -20
- package/dist/types/constants.d.ts +0 -5
- package/dist/types/core.d.ts +0 -38
- package/dist/types/errorcodes.d.ts +0 -93
- package/dist/types/helpers.d.ts +0 -2
- package/dist/types/index.d.ts +0 -4
- package/dist/types/modules/Api/Auth.d.ts +0 -3
- package/dist/types/modules/Api/Info.d.ts +0 -2
- package/dist/types/modules/Api/index.d.ts +0 -2
- package/dist/types/modules/AudioStation/Song.d.ts +0 -22
- package/dist/types/modules/AudioStation/index.d.ts +0 -5
- package/dist/types/modules/FileStation/File.d.ts +0 -0
- package/dist/types/modules/FileStation/Info.d.ts +0 -11
- package/dist/types/modules/FileStation/List.d.ts +0 -59
- package/dist/types/modules/FileStation/index.d.ts +0 -11
- package/dist/types/modules/index.d.ts +0 -9
- package/dist/types/types/apiInfo.d.ts +0 -39
- package/dist/types/types/index.d.ts +0 -2
- package/dist/types/types/request.d.ts +0 -8
- package/dist/types/utils.d.ts +0 -5
package/bin/syno
ADDED
|
@@ -70,7 +70,8 @@ __export(index_exports, {
|
|
|
70
70
|
FileStationApi: () => FileStationApi,
|
|
71
71
|
SynologyApi: () => SynologyApi,
|
|
72
72
|
SynologyApiInfo: () => SynologyApiInfo,
|
|
73
|
-
default: () => index_default
|
|
73
|
+
default: () => index_default,
|
|
74
|
+
loadCli: () => loadCli
|
|
74
75
|
});
|
|
75
76
|
module.exports = __toCommonJS(index_exports);
|
|
76
77
|
|
|
@@ -126,10 +127,11 @@ function getSongList(params) {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
// src/modules/AudioStation/index.ts
|
|
129
|
-
var
|
|
130
|
+
var METHODS = {
|
|
130
131
|
getSongList
|
|
131
132
|
};
|
|
132
|
-
var
|
|
133
|
+
var SPELLING_KEY = "AudioStation";
|
|
134
|
+
var SIMPLIFY_KEY = "as";
|
|
133
135
|
|
|
134
136
|
// src/modules/FileStation/Info.ts
|
|
135
137
|
function getInfo() {
|
|
@@ -187,15 +189,22 @@ function getFileListShare() {
|
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
// src/modules/FileStation/index.ts
|
|
190
|
-
var
|
|
192
|
+
var METHODS2 = {
|
|
191
193
|
getInfo,
|
|
192
194
|
getFileList,
|
|
193
195
|
getFileListShare
|
|
194
196
|
};
|
|
195
|
-
var
|
|
197
|
+
var SPELLING_KEY2 = "FileStation";
|
|
198
|
+
var SIMPLIFY_KEY2 = "fs";
|
|
196
199
|
|
|
197
200
|
// src/modules/index.ts
|
|
198
|
-
|
|
201
|
+
var SynologyApiKeys = {
|
|
202
|
+
FileStation: SPELLING_KEY2,
|
|
203
|
+
fs: SIMPLIFY_KEY2,
|
|
204
|
+
AudioStation: SPELLING_KEY,
|
|
205
|
+
as: SIMPLIFY_KEY
|
|
206
|
+
};
|
|
207
|
+
SPELLING_KEY, SIMPLIFY_KEY, SPELLING_KEY2, SIMPLIFY_KEY2;
|
|
199
208
|
var BaseSynologyApi = class {
|
|
200
209
|
constructor() {
|
|
201
210
|
}
|
|
@@ -208,14 +217,26 @@ function methodsBundler(instance, methods) {
|
|
|
208
217
|
return output;
|
|
209
218
|
}
|
|
210
219
|
Object.defineProperties(BaseSynologyApi.prototype, {
|
|
211
|
-
|
|
220
|
+
// FileStation
|
|
221
|
+
[SynologyApiKeys.FileStation]: {
|
|
222
|
+
get() {
|
|
223
|
+
return methodsBundler(this, METHODS2);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
[SynologyApiKeys.fs]: {
|
|
212
227
|
get() {
|
|
213
|
-
return methodsBundler(this,
|
|
228
|
+
return methodsBundler(this, METHODS2);
|
|
214
229
|
}
|
|
215
230
|
},
|
|
216
|
-
|
|
231
|
+
// AudioStation
|
|
232
|
+
[SynologyApiKeys.AudioStation]: {
|
|
217
233
|
get() {
|
|
218
|
-
return methodsBundler(this,
|
|
234
|
+
return methodsBundler(this, METHODS);
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
[SynologyApiKeys.as]: {
|
|
238
|
+
get() {
|
|
239
|
+
return methodsBundler(this, METHODS);
|
|
219
240
|
}
|
|
220
241
|
}
|
|
221
242
|
});
|
|
@@ -229,22 +250,22 @@ var QUICK_CONNECT_PINGPANG_API = "/webman/pingpong.cgi?action=cors&quickconnect=
|
|
|
229
250
|
|
|
230
251
|
// src/helpers.ts
|
|
231
252
|
var getServersFromServerInfo = (serverInfo) => __async(null, null, function* () {
|
|
232
|
-
var _a, _b;
|
|
233
|
-
if (serverInfo.service.relay_ip) {
|
|
253
|
+
var _a, _b, _c, _d, _e, _f;
|
|
254
|
+
if ((_a = serverInfo == null ? void 0 : serverInfo.service) == null ? void 0 : _a.relay_ip) {
|
|
234
255
|
const server = `http://${serverInfo.service.relay_ip}:${serverInfo.service.relay_port}`;
|
|
235
256
|
const res = yield pingpang(server);
|
|
236
257
|
if (res) {
|
|
237
258
|
return server;
|
|
238
259
|
}
|
|
239
260
|
}
|
|
240
|
-
if (serverInfo.server.external.ip) {
|
|
261
|
+
if ((_c = (_b = serverInfo == null ? void 0 : serverInfo.server) == null ? void 0 : _b.external) == null ? void 0 : _c.ip) {
|
|
241
262
|
const server = `http://${serverInfo.server.external.ip}:${serverInfo.service.port}`;
|
|
242
263
|
if (yield pingpang(server)) {
|
|
243
264
|
return server;
|
|
244
265
|
}
|
|
245
266
|
}
|
|
246
|
-
if ((
|
|
247
|
-
const server = `http://${(
|
|
267
|
+
if ((_e = (_d = serverInfo == null ? void 0 : serverInfo.server) == null ? void 0 : _d.interface) == null ? void 0 : _e[0]) {
|
|
268
|
+
const server = `http://${(_f = serverInfo.server.interface) == null ? void 0 : _f[0].ip}:${serverInfo.service.port}`;
|
|
248
269
|
if (yield pingpang(server)) {
|
|
249
270
|
return server;
|
|
250
271
|
}
|
|
@@ -349,7 +370,7 @@ function getApiInfo(core) {
|
|
|
349
370
|
var CODE_SUCCESS = 0;
|
|
350
371
|
var CODE_UNKNOWN = 9999;
|
|
351
372
|
var SYNOLOGY_ERROR_CODES = {
|
|
352
|
-
[
|
|
373
|
+
[SynologyApiKeys.FileStation]: {
|
|
353
374
|
400: "Invalid parameter of file operation",
|
|
354
375
|
401: "Unknown error of file operation",
|
|
355
376
|
402: "System is too busy",
|
|
@@ -374,7 +395,7 @@ var SYNOLOGY_ERROR_CODES = {
|
|
|
374
395
|
421: "Device or resource busy",
|
|
375
396
|
599: "No such task of the file operation"
|
|
376
397
|
},
|
|
377
|
-
[
|
|
398
|
+
[SynologyApiKeys.AudioStation]: {},
|
|
378
399
|
COMMON_CODES: {
|
|
379
400
|
[CODE_SUCCESS]: "Success",
|
|
380
401
|
100: "Unknown error",
|
|
@@ -540,6 +561,165 @@ var SynologyApi = class extends BaseSynologyApi {
|
|
|
540
561
|
}
|
|
541
562
|
};
|
|
542
563
|
|
|
564
|
+
// src/cli/index.ts
|
|
565
|
+
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
566
|
+
var import_path2 = __toESM(require("path"));
|
|
567
|
+
var import_commander3 = require("commander");
|
|
568
|
+
|
|
569
|
+
// src/cli/config.ts
|
|
570
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
571
|
+
var import_path = __toESM(require("path"));
|
|
572
|
+
var import_os = __toESM(require("os"));
|
|
573
|
+
var import_commander = require("commander");
|
|
574
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
575
|
+
|
|
576
|
+
// src/cli/helper.ts
|
|
577
|
+
var import_chalk = __toESM(require("chalk"));
|
|
578
|
+
function printMessages(messages) {
|
|
579
|
+
console.log(messages.join("\n"));
|
|
580
|
+
}
|
|
581
|
+
function isLowerCaseEqual(str1, str2) {
|
|
582
|
+
if (str1 && str2) {
|
|
583
|
+
return str1.toLowerCase() === str2.toLowerCase();
|
|
584
|
+
}
|
|
585
|
+
return !str1 && !str2;
|
|
586
|
+
}
|
|
587
|
+
function padding(message = "", before = 1, after = 1) {
|
|
588
|
+
return new Array(before).fill(" ").join("") + message + new Array(after).fill(" ").join("");
|
|
589
|
+
}
|
|
590
|
+
function geneDashLine(message, length) {
|
|
591
|
+
const finalMessage = new Array(Math.max(2, length - message.length + 2)).join(
|
|
592
|
+
"-"
|
|
593
|
+
);
|
|
594
|
+
return padding(import_chalk.default.dim(finalMessage));
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// src/cli/config.ts
|
|
598
|
+
var CONFIG_FILE_PATH = import_path.default.join(import_os.default.homedir(), "./.synology-api.json");
|
|
599
|
+
var loadConfig = () => __async(null, null, function* () {
|
|
600
|
+
if (!(yield import_fs_extra.default.pathExists(CONFIG_FILE_PATH))) {
|
|
601
|
+
yield import_fs_extra.default.writeJSON(CONFIG_FILE_PATH, {
|
|
602
|
+
used: "",
|
|
603
|
+
connections: {}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
const config = yield import_fs_extra.default.readJSON(CONFIG_FILE_PATH);
|
|
607
|
+
return config;
|
|
608
|
+
});
|
|
609
|
+
var updateConfig = (config) => __async(null, null, function* () {
|
|
610
|
+
yield import_fs_extra.default.writeJSON(CONFIG_FILE_PATH, config);
|
|
611
|
+
});
|
|
612
|
+
var configCmdRegister = () => {
|
|
613
|
+
const configCmd = import_commander.program.command("config").description("synology api config management");
|
|
614
|
+
configCmd.command("ls").description("List all the connection config").action(() => __async(null, null, function* () {
|
|
615
|
+
const config = yield loadConfig();
|
|
616
|
+
const keys = Object.keys(config.connections);
|
|
617
|
+
const dashLineLength = Math.max(...keys.map((key) => key.length)) + 3;
|
|
618
|
+
const messages = keys.map((key) => {
|
|
619
|
+
const connection = config.connections[key];
|
|
620
|
+
const prefix = isLowerCaseEqual(key, config.used) ? import_chalk2.default.green.bold("* ") : ":";
|
|
621
|
+
return prefix + key + geneDashLine(key, dashLineLength) + connection.server + ":" + connection.username + ":" + connection.password;
|
|
622
|
+
});
|
|
623
|
+
printMessages(messages);
|
|
624
|
+
}));
|
|
625
|
+
configCmd.command("add [name]").description("Add connection config").requiredOption("-s, --server <server>", "Synology server domain or QuickConnect ID ").requiredOption("-u, --username <username>", "username").requiredOption("-p, --password <password>", "password").action((name, options) => __async(null, null, function* () {
|
|
626
|
+
if (!name.trim()) throw new Error("Plaease input connection name");
|
|
627
|
+
const config = yield loadConfig();
|
|
628
|
+
const newConfig = __spreadProps(__spreadValues({}, config), {
|
|
629
|
+
connections: __spreadProps(__spreadValues({}, config.connections), {
|
|
630
|
+
[name]: {
|
|
631
|
+
server: options.server,
|
|
632
|
+
username: options.username,
|
|
633
|
+
password: options.password
|
|
634
|
+
}
|
|
635
|
+
})
|
|
636
|
+
});
|
|
637
|
+
yield updateConfig(newConfig);
|
|
638
|
+
}));
|
|
639
|
+
configCmd.command("use [name]").description("Change current connection").action((name) => __async(null, null, function* () {
|
|
640
|
+
const config = yield loadConfig();
|
|
641
|
+
if (config.used === name) return;
|
|
642
|
+
if (!config.connections[name]) {
|
|
643
|
+
console.log("Connection not found");
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
config.used = name;
|
|
647
|
+
yield updateConfig(config);
|
|
648
|
+
}));
|
|
649
|
+
configCmd.command("del [name]").description("Remove a connection").action((name) => __async(null, null, function* () {
|
|
650
|
+
console.log("Remove a connection", name);
|
|
651
|
+
const config = yield loadConfig();
|
|
652
|
+
if (!config.connections[name]) {
|
|
653
|
+
console.log("Connection not found");
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
delete config.connections[name];
|
|
657
|
+
if (config.used === name) {
|
|
658
|
+
config.used = "";
|
|
659
|
+
}
|
|
660
|
+
yield updateConfig(config);
|
|
661
|
+
}));
|
|
662
|
+
configCmd.command("rename <name> <newName>").description("Change connection name").action((name, newName) => __async(null, null, function* () {
|
|
663
|
+
const config = yield loadConfig();
|
|
664
|
+
if (!config.connections[name]) {
|
|
665
|
+
console.log("Connection not found");
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
config.connections[newName] = config.connections[name];
|
|
669
|
+
delete config.connections[name];
|
|
670
|
+
if (config.used === name) {
|
|
671
|
+
config.used = newName;
|
|
672
|
+
}
|
|
673
|
+
yield updateConfig(config);
|
|
674
|
+
}));
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
// src/cli/apis.ts
|
|
678
|
+
var import_commander2 = require("commander");
|
|
679
|
+
var onMethodsCall = (module2) => (method, options) => __async(null, null, function* () {
|
|
680
|
+
var _a, _b;
|
|
681
|
+
const config = yield loadConfig();
|
|
682
|
+
const params = JSON.parse(options.params || "{}");
|
|
683
|
+
const pretty = options.pretty;
|
|
684
|
+
const synologyApi = new SynologyApi(config.connections[config.used]);
|
|
685
|
+
if ((_a = synologyApi[module2]) == null ? void 0 : _a[method]) {
|
|
686
|
+
const result = yield (_b = synologyApi[module2]) == null ? void 0 : _b[method](params);
|
|
687
|
+
if (pretty) {
|
|
688
|
+
console.log(JSON.stringify(result, null, 2));
|
|
689
|
+
} else {
|
|
690
|
+
console.log(JSON.stringify(result));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
synologyApi.disconnect();
|
|
694
|
+
process.exit(0);
|
|
695
|
+
});
|
|
696
|
+
var apisCmdRegisterInfo = [
|
|
697
|
+
{
|
|
698
|
+
cmd: SynologyApiKeys.FileStation,
|
|
699
|
+
alias: SynologyApiKeys.fs
|
|
700
|
+
},
|
|
701
|
+
{
|
|
702
|
+
cmd: SynologyApiKeys.AudioStation,
|
|
703
|
+
alias: SynologyApiKeys.as
|
|
704
|
+
}
|
|
705
|
+
];
|
|
706
|
+
var apiCmdRegister = () => {
|
|
707
|
+
apisCmdRegisterInfo.forEach((info) => {
|
|
708
|
+
import_commander2.program.command(`${info.cmd} [methods]`).alias(info.alias).option("-p,--params <params>", `${info.cmd} methods params`).option("--pretty", "Prettyprint JSON Output").description(`Synology ${info.cmd} method call`).action(onMethodsCall(info.cmd));
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
// src/cli/index.ts
|
|
713
|
+
function loadCli() {
|
|
714
|
+
return __async(this, null, function* () {
|
|
715
|
+
const pkg = yield import_fs_extra2.default.readJSON(import_path2.default.join(__dirname, "../../package.json"));
|
|
716
|
+
import_commander3.program.name("synology").usage("<command> [options]").description("synology api cli tool").version(pkg.version);
|
|
717
|
+
configCmdRegister();
|
|
718
|
+
apiCmdRegister();
|
|
719
|
+
import_commander3.program.parse(process.argv);
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
|
|
543
723
|
// src/index.ts
|
|
544
724
|
var index_default = SynologyApi;
|
|
545
725
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -547,5 +727,6 @@ var index_default = SynologyApi;
|
|
|
547
727
|
AudioStationApi,
|
|
548
728
|
FileStationApi,
|
|
549
729
|
SynologyApi,
|
|
550
|
-
SynologyApiInfo
|
|
730
|
+
SynologyApiInfo,
|
|
731
|
+
loadCli
|
|
551
732
|
});
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fett/synology-api",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.6",
|
|
4
4
|
"description": "synology api for nodejs",
|
|
5
|
-
"module": "./
|
|
6
|
-
"main": "./
|
|
7
|
-
"types": "./
|
|
5
|
+
"module": "./lib/esm/index.js",
|
|
6
|
+
"main": "./lib/cjs/index.js",
|
|
7
|
+
"types": "./lib/types/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"require": "./
|
|
11
|
-
"import": "./
|
|
10
|
+
"require": "./lib/cjs/index.js",
|
|
11
|
+
"import": "./lib/esm/index.js"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"synology": "./bin/syno",
|
|
16
|
+
"syno": "./bin/syno"
|
|
17
|
+
},
|
|
14
18
|
"files": [
|
|
15
|
-
"
|
|
19
|
+
"lib",
|
|
20
|
+
"bin"
|
|
16
21
|
],
|
|
17
22
|
"author": "ChrisSong1994 <https://github.com/ChrisSong1994>",
|
|
18
23
|
"keywords": [
|
|
@@ -26,11 +31,12 @@
|
|
|
26
31
|
"commonjs"
|
|
27
32
|
],
|
|
28
33
|
"scripts": {
|
|
29
|
-
"dev": "tsc --sourceMap --watch && tsc-alias",
|
|
34
|
+
"dev:esm": "tsc --sourceMap --watch && tsc-alias",
|
|
35
|
+
"dev:cjs": "tsup --config tsup.config.ts --watch ",
|
|
30
36
|
"build:cjs": "tsup --config tsup.config.ts",
|
|
31
37
|
"build:esm": "tsc && tsc-alias",
|
|
32
38
|
"build": "npm run clean && npm run build:cjs && npm run build:esm",
|
|
33
|
-
"clean": "rimraf
|
|
39
|
+
"clean": "rimraf lib",
|
|
34
40
|
"lint": "eslint src --ext .ts --fix",
|
|
35
41
|
"prettier": "prettier --write 'src/**/*.ts'",
|
|
36
42
|
"format": "npm run prettier && npm run lint",
|
|
@@ -44,6 +50,7 @@
|
|
|
44
50
|
"devDependencies": {
|
|
45
51
|
"@eslint/js": "^9.26.0",
|
|
46
52
|
"eslint": "9.25.1",
|
|
53
|
+
"execa": "^9.6.0",
|
|
47
54
|
"globals": "^16.1.0",
|
|
48
55
|
"prettier": "3.5.3",
|
|
49
56
|
"rimraf": "^6.0.1",
|
|
@@ -56,6 +63,10 @@
|
|
|
56
63
|
"vitest": "^3.1.3"
|
|
57
64
|
},
|
|
58
65
|
"dependencies": {
|
|
59
|
-
"axios": "^1.9.0"
|
|
66
|
+
"axios": "^1.9.0",
|
|
67
|
+
"chalk": "^5.4.1",
|
|
68
|
+
"commander": "^14.0.0",
|
|
69
|
+
"fs-extra": "^11.3.0",
|
|
70
|
+
"ora": "^8.2.0"
|
|
60
71
|
}
|
|
61
72
|
}
|
package/dist/esm/constants.js
DELETED
package/dist/esm/core.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
// reference: https://kb.synology.com/zh-tw/DSM/tutorial/What_websites_does_Synology_NAS_connect_to_when_running_services_or_updating_software
|
|
11
|
-
import axios from "axios";
|
|
12
|
-
import { BaseSynologyApi } from "./modules";
|
|
13
|
-
import { isHttpUrl, getApiKey, isUndfined } from "./utils";
|
|
14
|
-
import { getServerInfo } from "./helpers";
|
|
15
|
-
import { login, logout, getApiInfo } from "./modules/Api";
|
|
16
|
-
import { resWithErrorCode } from "./errorcodes";
|
|
17
|
-
export class SynologyApi extends BaseSynologyApi {
|
|
18
|
-
constructor(options) {
|
|
19
|
-
super();
|
|
20
|
-
this.isConnecting = false;
|
|
21
|
-
this.authInfo = null;
|
|
22
|
-
this.apiInfo = {};
|
|
23
|
-
this.server = options.server;
|
|
24
|
-
this.username = options.username;
|
|
25
|
-
this.password = options.password;
|
|
26
|
-
this.baseUrl = `${this.server}/webapi/`;
|
|
27
|
-
}
|
|
28
|
-
connect() {
|
|
29
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
-
// if quickconnect id
|
|
31
|
-
if (!isHttpUrl(this.server)) {
|
|
32
|
-
this.server = yield getServerInfo(this.server);
|
|
33
|
-
// reset base url
|
|
34
|
-
this.baseUrl = `${this.server}/webapi/`;
|
|
35
|
-
}
|
|
36
|
-
try {
|
|
37
|
-
const result = yield login(this);
|
|
38
|
-
this.authInfo = result.data;
|
|
39
|
-
this.isConnecting = true;
|
|
40
|
-
yield this._getApiInfo();
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
catch (err) {
|
|
44
|
-
console.error(err);
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
disconnect() {
|
|
50
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
-
try {
|
|
52
|
-
yield logout(this);
|
|
53
|
-
this.authInfo = null;
|
|
54
|
-
this.apiInfo = {};
|
|
55
|
-
this.isConnecting = false;
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
catch (err) {
|
|
59
|
-
console.error(err);
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
_getApiInfo() {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
try {
|
|
67
|
-
const result = yield getApiInfo(this);
|
|
68
|
-
this.apiInfo = result.data;
|
|
69
|
-
}
|
|
70
|
-
catch (err) {
|
|
71
|
-
console.error(err);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
hasApi(apiName) {
|
|
76
|
-
if (!this.isConnecting) {
|
|
77
|
-
throw new Error("Not connected");
|
|
78
|
-
}
|
|
79
|
-
return Object.prototype.hasOwnProperty.call(this.apiInfo, apiName);
|
|
80
|
-
}
|
|
81
|
-
run(apiName, options) {
|
|
82
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
-
if (!this.isConnecting) {
|
|
84
|
-
const res = yield this.connect();
|
|
85
|
-
if (!res) {
|
|
86
|
-
throw new Error("Not connected");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (!this.hasApi(apiName)) {
|
|
90
|
-
throw new Error(`${apiName} not found`);
|
|
91
|
-
}
|
|
92
|
-
const { method = "get", params, data, headers } = options;
|
|
93
|
-
const api = this.apiInfo[apiName];
|
|
94
|
-
const url = `${this.baseUrl}${api.path}`;
|
|
95
|
-
const externalParams = Object.assign({ api: apiName, version: api.maxVersion, _sid: this.authInfo.sid }, params);
|
|
96
|
-
let result = null;
|
|
97
|
-
if (method === "get") {
|
|
98
|
-
result = yield axios.get(url, { params: externalParams, data, headers });
|
|
99
|
-
}
|
|
100
|
-
if (method === "post") {
|
|
101
|
-
result = yield axios.post(url, { params: externalParams, data, headers });
|
|
102
|
-
}
|
|
103
|
-
// match error code msg
|
|
104
|
-
const apiKey = getApiKey(apiName);
|
|
105
|
-
if (!isUndfined(apiKey)) {
|
|
106
|
-
result.data = resWithErrorCode(apiKey, result.data);
|
|
107
|
-
}
|
|
108
|
-
return result;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
package/dist/esm/errorcodes.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { FileStationKey, AudioStationKey } from "./modules";
|
|
2
|
-
import { isUndfined } from "./utils";
|
|
3
|
-
const CODE_SUCCESS = 0;
|
|
4
|
-
const CODE_UNKNOWN = 9999;
|
|
5
|
-
export const SYNOLOGY_ERROR_CODES = {
|
|
6
|
-
[FileStationKey]: {
|
|
7
|
-
400: "Invalid parameter of file operation",
|
|
8
|
-
401: "Unknown error of file operation",
|
|
9
|
-
402: "System is too busy",
|
|
10
|
-
403: "Invalid user does this file operation",
|
|
11
|
-
404: "Invalid group does this file operation",
|
|
12
|
-
405: "Invalid user and group does this file operation",
|
|
13
|
-
406: "Can't get user/group information from the account server",
|
|
14
|
-
407: "Operation not permitted",
|
|
15
|
-
408: "No such file or directory",
|
|
16
|
-
409: "Non-supported file system",
|
|
17
|
-
410: "Failed to connect internet-based file system (e.g., CIFS)",
|
|
18
|
-
411: "Read-only file system",
|
|
19
|
-
412: "Filename too long in the non-encrypted file system",
|
|
20
|
-
413: "Filename too long in the encrypted file system",
|
|
21
|
-
414: "File already exists",
|
|
22
|
-
415: "Disk quota exceeded",
|
|
23
|
-
416: "No space left on device",
|
|
24
|
-
417: "Input/output error",
|
|
25
|
-
418: "Illegal name or path",
|
|
26
|
-
419: "Illegal file name",
|
|
27
|
-
420: "Illegal file name on FAT file system",
|
|
28
|
-
421: "Device or resource busy",
|
|
29
|
-
599: "No such task of the file operation",
|
|
30
|
-
},
|
|
31
|
-
[AudioStationKey]: {},
|
|
32
|
-
COMMON_CODES: {
|
|
33
|
-
[CODE_SUCCESS]: "Success",
|
|
34
|
-
100: "Unknown error",
|
|
35
|
-
101: "No parameter of API, method or version",
|
|
36
|
-
102: "The requested API does not exist",
|
|
37
|
-
103: "The requested method does not exist",
|
|
38
|
-
104: "The requested version does not support the functionality",
|
|
39
|
-
105: "The logged in session does not have permission",
|
|
40
|
-
106: "Session timeout",
|
|
41
|
-
107: "Session interrupted by duplicated login",
|
|
42
|
-
108: "Failed to upload the file",
|
|
43
|
-
109: "The network connection is unstable or the system is busy",
|
|
44
|
-
110: "The network connection is unstable or the system is busy",
|
|
45
|
-
111: "The network connection is unstable or the system is busy",
|
|
46
|
-
112: "Preserve for other purpose",
|
|
47
|
-
113: "Preserve for other purpose",
|
|
48
|
-
114: "Lost parameters for this API",
|
|
49
|
-
115: "Not allowed to upload a file",
|
|
50
|
-
116: "Not allowed to perform for a demo site",
|
|
51
|
-
117: "The network connection is unstable or the system is busy",
|
|
52
|
-
118: "The network connection is unstable or the system is busy",
|
|
53
|
-
119: "Invalid session / SID not found.",
|
|
54
|
-
// # 120-149 Preserve for other purpose
|
|
55
|
-
120: "Preserve for other purpose",
|
|
56
|
-
121: "Preserve for other purpose",
|
|
57
|
-
122: "Preserve for other purpose",
|
|
58
|
-
123: "Preserve for other purpose",
|
|
59
|
-
124: "Preserve for other purpose",
|
|
60
|
-
125: "Preserve for other purpose",
|
|
61
|
-
126: "Preserve for other purpose",
|
|
62
|
-
127: "Preserve for other purpose",
|
|
63
|
-
128: "Preserve for other purpose",
|
|
64
|
-
129: "Preserve for other purpose",
|
|
65
|
-
130: "Preserve for other purpose",
|
|
66
|
-
131: "Preserve for other purpose",
|
|
67
|
-
132: "Preserve for other purpose",
|
|
68
|
-
133: "Preserve for other purpose",
|
|
69
|
-
134: "Preserve for other purpose",
|
|
70
|
-
135: "Preserve for other purpose",
|
|
71
|
-
136: "Preserve for other purpose",
|
|
72
|
-
137: "Preserve for other purpose",
|
|
73
|
-
138: "Preserve for other purpose",
|
|
74
|
-
139: "Preserve for other purpose",
|
|
75
|
-
140: "Preserve for other purpose",
|
|
76
|
-
141: "Preserve for other purpose",
|
|
77
|
-
142: "Preserve for other purpose",
|
|
78
|
-
143: "Preserve for other purpose",
|
|
79
|
-
144: "Preserve for other purpose",
|
|
80
|
-
145: "Preserve for other purpose",
|
|
81
|
-
146: "Preserve for other purpose",
|
|
82
|
-
147: "Preserve for other purpose",
|
|
83
|
-
148: "Preserve for other purpose",
|
|
84
|
-
149: "Preserve for other purpose",
|
|
85
|
-
150: "Request source IP does not match the login IP",
|
|
86
|
-
160: "Insufficient application privilege",
|
|
87
|
-
[CODE_UNKNOWN]: "Unknown error",
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
export const resWithErrorCode = (apiKey, res) => {
|
|
91
|
-
var _a, _b;
|
|
92
|
-
const errorCodes = SYNOLOGY_ERROR_CODES[apiKey];
|
|
93
|
-
const code = (_a = res === null || res === void 0 ? void 0 : res.error) === null || _a === void 0 ? void 0 : _a.code;
|
|
94
|
-
if (isUndfined(code))
|
|
95
|
-
return res;
|
|
96
|
-
return Object.assign(Object.assign({}, res), { error: Object.assign(Object.assign({}, res.error), { message: ((_b = res === null || res === void 0 ? void 0 : res.error) === null || _b === void 0 ? void 0 : _b.message) || (errorCodes === null || errorCodes === void 0 ? void 0 : errorCodes[code]) || "Unknown error" }) });
|
|
97
|
-
};
|
package/dist/esm/helpers.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import axios from "axios";
|
|
11
|
-
import { GLOBAL_QUICK_CONNECT_URL, QUICK_CONNECT_PINGPANG_API } from "./constants";
|
|
12
|
-
const getServersFromServerInfo = (serverInfo) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
-
var _a, _b;
|
|
14
|
-
// proxy server
|
|
15
|
-
if (serverInfo.service.relay_ip) {
|
|
16
|
-
const server = `http://${serverInfo.service.relay_ip}:${serverInfo.service.relay_port}`;
|
|
17
|
-
const res = yield pingpang(server);
|
|
18
|
-
if (res) {
|
|
19
|
-
return server;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
// WAN IP
|
|
23
|
-
if (serverInfo.server.external.ip) {
|
|
24
|
-
const server = `http://${serverInfo.server.external.ip}:${serverInfo.service.port}`;
|
|
25
|
-
if (yield pingpang(server)) {
|
|
26
|
-
return server;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
// lan ip
|
|
30
|
-
if ((_a = serverInfo.server.interface) === null || _a === void 0 ? void 0 : _a[0]) {
|
|
31
|
-
const server = `http://${(_b = serverInfo.server.interface) === null || _b === void 0 ? void 0 : _b[0].ip}:${serverInfo.service.port}`;
|
|
32
|
-
if (yield pingpang(server)) {
|
|
33
|
-
return server;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
// get server ip
|
|
38
|
-
export const getServerInfo = (quickConnectId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
39
|
-
var _a, _b, _c, _d;
|
|
40
|
-
const params = {
|
|
41
|
-
version: 1,
|
|
42
|
-
id: "dsm",
|
|
43
|
-
serverID: quickConnectId,
|
|
44
|
-
get_ca_fingerprints: true,
|
|
45
|
-
command: "get_server_info",
|
|
46
|
-
};
|
|
47
|
-
const serverInfo = yield axios.post(GLOBAL_QUICK_CONNECT_URL, params);
|
|
48
|
-
if (!((_b = (_a = serverInfo.data) === null || _a === void 0 ? void 0 : _a.service) === null || _b === void 0 ? void 0 : _b.relay_ip) && !((_d = (_c = serverInfo.data) === null || _c === void 0 ? void 0 : _c.service) === null || _d === void 0 ? void 0 : _d.relay_port)) {
|
|
49
|
-
const relayRequestParams = {
|
|
50
|
-
version: 1,
|
|
51
|
-
id: "dsm",
|
|
52
|
-
serverID: quickConnectId,
|
|
53
|
-
platform: "web",
|
|
54
|
-
command: "request_tunnel",
|
|
55
|
-
};
|
|
56
|
-
const result = yield axios.post(`https://${serverInfo.data.env.control_host}/Serv.php`, relayRequestParams);
|
|
57
|
-
return getServersFromServerInfo(result.data);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
return getServersFromServerInfo(serverInfo.data);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
// pingpang
|
|
64
|
-
export const pingpang = (server) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
-
try {
|
|
66
|
-
const result = yield axios.get(`${server}/${QUICK_CONNECT_PINGPANG_API}`, {
|
|
67
|
-
timeout: 3000,
|
|
68
|
-
});
|
|
69
|
-
if (result.data.success) {
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
76
|
-
}
|
|
77
|
-
catch (_err) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
});
|
package/dist/esm/index.js
DELETED