@fett/synology-api 0.0.1-beta.6 → 0.0.1-beta.8

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 (48) hide show
  1. package/lib/cjs/index.js +4 -3
  2. package/lib/esm/cli/apis.js +53 -0
  3. package/lib/esm/cli/config.js +130 -0
  4. package/lib/esm/cli/helper.js +19 -0
  5. package/lib/esm/cli/index.js +30 -0
  6. package/lib/esm/constants.js +5 -0
  7. package/lib/esm/core.js +111 -0
  8. package/lib/esm/errorcodes.js +97 -0
  9. package/lib/esm/helpers.js +80 -0
  10. package/lib/esm/index.js +5 -0
  11. package/lib/esm/modules/Api/Auth.js +43 -0
  12. package/lib/esm/modules/Api/Info.js +26 -0
  13. package/lib/esm/modules/Api/index.js +2 -0
  14. package/lib/esm/modules/AudioStation/Song.js +18 -0
  15. package/lib/esm/modules/AudioStation/index.js +7 -0
  16. package/lib/esm/modules/FileStation/File.js +0 -0
  17. package/lib/esm/modules/FileStation/Info.js +20 -0
  18. package/lib/esm/modules/FileStation/List.js +32 -0
  19. package/lib/esm/modules/FileStation/index.js +14 -0
  20. package/lib/esm/modules/index.js +46 -0
  21. package/lib/esm/types/apiInfo.js +42 -0
  22. package/lib/esm/types/index.js +2 -0
  23. package/lib/esm/types/request.js +2 -0
  24. package/lib/esm/utils.js +20 -0
  25. package/lib/types/cli/apis.d.ts +6 -0
  26. package/lib/types/cli/config.d.ts +13 -0
  27. package/lib/types/cli/helper.d.ts +4 -0
  28. package/lib/types/cli/index.d.ts +1 -0
  29. package/lib/types/constants.d.ts +5 -0
  30. package/lib/types/core.d.ts +38 -0
  31. package/lib/types/errorcodes.d.ts +94 -0
  32. package/lib/types/helpers.d.ts +2 -0
  33. package/lib/types/index.d.ts +5 -0
  34. package/lib/types/modules/Api/Auth.d.ts +3 -0
  35. package/lib/types/modules/Api/Info.d.ts +2 -0
  36. package/lib/types/modules/Api/index.d.ts +2 -0
  37. package/lib/types/modules/AudioStation/Song.d.ts +22 -0
  38. package/lib/types/modules/AudioStation/index.d.ts +7 -0
  39. package/lib/types/modules/FileStation/File.d.ts +0 -0
  40. package/lib/types/modules/FileStation/Info.d.ts +11 -0
  41. package/lib/types/modules/FileStation/List.d.ts +59 -0
  42. package/lib/types/modules/FileStation/index.d.ts +13 -0
  43. package/lib/types/modules/index.d.ts +16 -0
  44. package/lib/types/types/apiInfo.d.ts +39 -0
  45. package/lib/types/types/index.d.ts +2 -0
  46. package/lib/types/types/request.d.ts +8 -0
  47. package/lib/types/utils.d.ts +5 -0
  48. package/package.json +3 -2
package/lib/cjs/index.js CHANGED
@@ -595,9 +595,10 @@ function geneDashLine(message, length) {
595
595
  }
596
596
 
597
597
  // src/cli/config.ts
598
- var CONFIG_FILE_PATH = import_path.default.join(import_os.default.homedir(), "./.synology-api.json");
598
+ var CONFIG_FILE_PATH = process.env.NODE_ENV === "development" ? import_path.default.join(process.cwd(), "./.userdata/.synology-api.json") : import_path.default.join(import_os.default.homedir(), "./.synology-api.json");
599
599
  var loadConfig = () => __async(null, null, function* () {
600
600
  if (!(yield import_fs_extra.default.pathExists(CONFIG_FILE_PATH))) {
601
+ yield import_fs_extra.default.ensureFile(CONFIG_FILE_PATH);
601
602
  yield import_fs_extra.default.writeJSON(CONFIG_FILE_PATH, {
602
603
  used: "",
603
604
  connections: {}
@@ -617,7 +618,7 @@ var configCmdRegister = () => {
617
618
  const dashLineLength = Math.max(...keys.map((key) => key.length)) + 3;
618
619
  const messages = keys.map((key) => {
619
620
  const connection = config.connections[key];
620
- const prefix = isLowerCaseEqual(key, config.used) ? import_chalk2.default.green.bold("* ") : ":";
621
+ const prefix = isLowerCaseEqual(key, config.used) ? import_chalk2.default.green.bold("* ") : " ";
621
622
  return prefix + key + geneDashLine(key, dashLineLength) + connection.server + ":" + connection.username + ":" + connection.password;
622
623
  });
623
624
  printMessages(messages);
@@ -713,7 +714,7 @@ var apiCmdRegister = () => {
713
714
  function loadCli() {
714
715
  return __async(this, null, function* () {
715
716
  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
+ import_commander3.program.name("synology").usage("<command> [options]").description("synology api cli tool").version(pkg.version, "-v, --version", "output the version number");
717
718
  configCmdRegister();
718
719
  apiCmdRegister();
719
720
  import_commander3.program.parse(process.argv);
@@ -0,0 +1,53 @@
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 { program } from "commander";
11
+ import { loadConfig } from "./config";
12
+ import { SynologyApi } from "../core";
13
+ import { SynologyApiKeys } from "../modules";
14
+ export const onMethodsCall = (module) => (method, options) => __awaiter(void 0, void 0, void 0, function* () {
15
+ var _a, _b;
16
+ const config = yield loadConfig();
17
+ const params = JSON.parse(options.params || "{}");
18
+ const pretty = options.pretty;
19
+ const synologyApi = new SynologyApi(config.connections[config.used]);
20
+ if ((_a = synologyApi[module]) === null || _a === void 0 ? void 0 : _a[method]) {
21
+ const result = yield ((_b = synologyApi[module]) === null || _b === void 0 ? void 0 : _b[method](params));
22
+ if (pretty) {
23
+ console.log(JSON.stringify(result, null, 2));
24
+ }
25
+ else {
26
+ console.log(JSON.stringify(result));
27
+ }
28
+ }
29
+ synologyApi.disconnect();
30
+ process.exit(0);
31
+ });
32
+ // register all modules
33
+ const apisCmdRegisterInfo = [
34
+ {
35
+ cmd: SynologyApiKeys.FileStation,
36
+ alias: SynologyApiKeys.fs,
37
+ },
38
+ {
39
+ cmd: SynologyApiKeys.AudioStation,
40
+ alias: SynologyApiKeys.as,
41
+ },
42
+ ];
43
+ export const apiCmdRegister = () => {
44
+ apisCmdRegisterInfo.forEach((info) => {
45
+ program
46
+ .command(`${info.cmd} [methods]`)
47
+ .alias(info.alias)
48
+ .option("-p,--params <params>", `${info.cmd} methods params`)
49
+ .option("--pretty", "Prettyprint JSON Output")
50
+ .description(`Synology ${info.cmd} method call`)
51
+ .action(onMethodsCall(info.cmd));
52
+ });
53
+ };
@@ -0,0 +1,130 @@
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 fse from "fs-extra";
11
+ import path from "path";
12
+ import os from "os";
13
+ import { program } from "commander";
14
+ import chalk from "chalk";
15
+ import { isLowerCaseEqual, printMessages, geneDashLine } from "./helper";
16
+ const CONFIG_FILE_PATH = process.env.NODE_ENV === "development"
17
+ ? path.join(process.cwd(), "./.userdata/.synology-api.json") // development
18
+ : path.join(os.homedir(), "./.synology-api.json");
19
+ // load config
20
+ export const loadConfig = () => __awaiter(void 0, void 0, void 0, function* () {
21
+ if (!(yield fse.pathExists(CONFIG_FILE_PATH))) {
22
+ yield fse.ensureFile(CONFIG_FILE_PATH);
23
+ yield fse.writeJSON(CONFIG_FILE_PATH, {
24
+ used: "",
25
+ connections: {},
26
+ });
27
+ }
28
+ const config = yield fse.readJSON(CONFIG_FILE_PATH);
29
+ return config;
30
+ });
31
+ // update config
32
+ export const updateConfig = (config) => __awaiter(void 0, void 0, void 0, function* () {
33
+ yield fse.writeJSON(CONFIG_FILE_PATH, config);
34
+ });
35
+ // check config
36
+ export const checkConfig = () => __awaiter(void 0, void 0, void 0, function* () { });
37
+ export const configCmdRegister = () => {
38
+ const configCmd = program.command("config").description("synology api config management");
39
+ // list connection config
40
+ configCmd
41
+ .command("ls")
42
+ .description("List all the connection config")
43
+ .action(() => __awaiter(void 0, void 0, void 0, function* () {
44
+ const config = yield loadConfig();
45
+ const keys = Object.keys(config.connections);
46
+ const dashLineLength = Math.max(...keys.map((key) => key.length)) + 3;
47
+ const messages = keys.map((key) => {
48
+ const connection = config.connections[key];
49
+ const prefix = isLowerCaseEqual(key, config.used) ? chalk.green.bold("* ") : " ";
50
+ return (prefix +
51
+ key +
52
+ geneDashLine(key, dashLineLength) +
53
+ connection.server +
54
+ ":" +
55
+ connection.username +
56
+ ":" +
57
+ connection.password);
58
+ });
59
+ printMessages(messages);
60
+ }));
61
+ // add connection
62
+ configCmd
63
+ .command("add [name]")
64
+ .description("Add connection config")
65
+ .requiredOption("-s, --server <server>", "Synology server domain or QuickConnect ID ")
66
+ .requiredOption("-u, --username <username>", "username")
67
+ .requiredOption("-p, --password <password>", "password")
68
+ .action((name, options) => __awaiter(void 0, void 0, void 0, function* () {
69
+ if (!name.trim())
70
+ throw new Error("Plaease input connection name");
71
+ // 实际代码中应保存配置到文件
72
+ const config = yield loadConfig();
73
+ const newConfig = Object.assign(Object.assign({}, config), { connections: Object.assign(Object.assign({}, config.connections), { [name]: {
74
+ server: options.server,
75
+ username: options.username,
76
+ password: options.password,
77
+ } }) });
78
+ yield updateConfig(newConfig);
79
+ }));
80
+ // use connection
81
+ configCmd
82
+ .command("use [name]")
83
+ .description("Change current connection")
84
+ .action((name) => __awaiter(void 0, void 0, void 0, function* () {
85
+ const config = yield loadConfig();
86
+ if (config.used === name)
87
+ return;
88
+ if (!config.connections[name]) {
89
+ console.log("Connection not found");
90
+ return;
91
+ }
92
+ config.used = name;
93
+ yield updateConfig(config);
94
+ }));
95
+ // del connection
96
+ configCmd
97
+ .command("del [name]")
98
+ .description("Remove a connection")
99
+ .action((name) => __awaiter(void 0, void 0, void 0, function* () {
100
+ console.log("Remove a connection", name);
101
+ const config = yield loadConfig();
102
+ // 删除配置
103
+ if (!config.connections[name]) {
104
+ console.log("Connection not found");
105
+ return;
106
+ }
107
+ delete config.connections[name];
108
+ if (config.used === name) {
109
+ config.used = "";
110
+ }
111
+ yield updateConfig(config);
112
+ }));
113
+ // Change connection name
114
+ configCmd
115
+ .command("rename <name> <newName>")
116
+ .description("Change connection name")
117
+ .action((name, newName) => __awaiter(void 0, void 0, void 0, function* () {
118
+ const config = yield loadConfig();
119
+ if (!config.connections[name]) {
120
+ console.log("Connection not found");
121
+ return;
122
+ }
123
+ config.connections[newName] = config.connections[name];
124
+ delete config.connections[name];
125
+ if (config.used === name) {
126
+ config.used = newName;
127
+ }
128
+ yield updateConfig(config);
129
+ }));
130
+ };
@@ -0,0 +1,19 @@
1
+ import chalk from "chalk";
2
+ export function printMessages(messages) {
3
+ console.log(messages.join("\n"));
4
+ }
5
+ export function isLowerCaseEqual(str1, str2) {
6
+ if (str1 && str2) {
7
+ return str1.toLowerCase() === str2.toLowerCase();
8
+ }
9
+ return !str1 && !str2;
10
+ }
11
+ export function padding(message = '', before = 1, after = 1) {
12
+ return (new Array(before).fill(' ').join('') +
13
+ message +
14
+ new Array(after).fill(' ').join(''));
15
+ }
16
+ export function geneDashLine(message, length) {
17
+ const finalMessage = new Array(Math.max(2, length - message.length + 2)).join('-');
18
+ return padding(chalk.dim(finalMessage));
19
+ }
@@ -0,0 +1,30 @@
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 fse from "fs-extra";
11
+ import path from "path";
12
+ import { program } from "commander";
13
+ import { configCmdRegister } from "./config";
14
+ import { apiCmdRegister } from "./apis";
15
+ export function loadCli() {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ // git program info
18
+ const pkg = yield fse.readJSON(path.join(__dirname, "../../package.json"));
19
+ // command
20
+ program
21
+ .name("synology")
22
+ .usage("<command> [options]")
23
+ .description("synology api cli tool")
24
+ .version(pkg.version, "-v, --version", "output the version number");
25
+ // register commands
26
+ configCmdRegister();
27
+ apiCmdRegister();
28
+ program.parse(process.argv);
29
+ });
30
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * synology constants
3
+ */
4
+ export const GLOBAL_QUICK_CONNECT_URL = "https://global.quickconnect.cn/Serv.php";
5
+ export const QUICK_CONNECT_PINGPANG_API = "/webman/pingpong.cgi?action=cors&quickconnect=true";
@@ -0,0 +1,111 @@
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
+ }
@@ -0,0 +1,97 @@
1
+ import { SynologyApiKeys } from "./modules";
2
+ import { isUndfined } from "./utils";
3
+ const CODE_SUCCESS = 0;
4
+ const CODE_UNKNOWN = 9999;
5
+ export const SYNOLOGY_ERROR_CODES = {
6
+ [SynologyApiKeys.FileStation]: {
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
+ [SynologyApiKeys.AudioStation]: {},
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
+ };
@@ -0,0 +1,80 @@
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, _c, _d, _e, _f;
14
+ // proxy server
15
+ if ((_a = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.service) === null || _a === void 0 ? void 0 : _a.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 ((_c = (_b = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.server) === null || _b === void 0 ? void 0 : _b.external) === null || _c === void 0 ? void 0 : _c.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 ((_e = (_d = serverInfo === null || serverInfo === void 0 ? void 0 : serverInfo.server) === null || _d === void 0 ? void 0 : _d.interface) === null || _e === void 0 ? void 0 : _e[0]) {
31
+ const server = `http://${(_f = serverInfo.server.interface) === null || _f === void 0 ? void 0 : _f[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
+ });
@@ -0,0 +1,5 @@
1
+ import { SynologyApi } from "./core";
2
+ export * from "./types";
3
+ export * from "./core";
4
+ export * from "./cli";
5
+ export default SynologyApi;
@@ -0,0 +1,43 @@
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 { SynologyApiInfo } from "../../types";
12
+ export function login(core) {
13
+ return __awaiter(this, void 0, void 0, function* () {
14
+ const params = {
15
+ api: SynologyApiInfo.Auth,
16
+ version: 6,
17
+ method: "login",
18
+ account: core.username,
19
+ passwd: core.password,
20
+ format: "sid",
21
+ };
22
+ const url = `${core.baseUrl}entry.cgi`;
23
+ const result = yield axios.get(url, { params });
24
+ if (!result.data.success) {
25
+ throw new Error(result.data.error.message);
26
+ }
27
+ return result.data;
28
+ });
29
+ }
30
+ export function logout(core) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const params = {
33
+ api: SynologyApiInfo.Auth,
34
+ version: 6,
35
+ method: "logout",
36
+ };
37
+ const url = `${core.baseUrl}entry.cgi`;
38
+ const result = yield axios.get(url, { params });
39
+ if (!result.data.success) {
40
+ throw new Error(result.data.error.message);
41
+ }
42
+ });
43
+ }
@@ -0,0 +1,26 @@
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 { SynologyApiInfo } from "../../types";
12
+ export function getApiInfo(core) {
13
+ return __awaiter(this, void 0, void 0, function* () {
14
+ const params = {
15
+ api: SynologyApiInfo.Info,
16
+ version: 1,
17
+ method: "query",
18
+ };
19
+ const url = `${core.baseUrl}entry.cgi`;
20
+ const result = yield axios.get(url, { params });
21
+ if (!result.data.success) {
22
+ throw new Error(result.data.error.message);
23
+ }
24
+ return result.data;
25
+ });
26
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./Auth";
2
+ export * from "./Info";
@@ -0,0 +1,18 @@
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 { AudioStationApi } from "../../types";
11
+ export function getSongList(params) {
12
+ return __awaiter(this, void 0, void 0, function* () {
13
+ const res = yield this.run(AudioStationApi.Song, {
14
+ params: Object.assign({ method: "list", library: "all" }, params),
15
+ });
16
+ return res.data;
17
+ });
18
+ }