@fett/synology-api 0.0.1-beta.2 → 0.0.1-beta.4
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 +7 -3
- package/dist/cjs/index.js +551 -19
- package/dist/esm/constants.js +3 -2
- package/dist/esm/core.js +11 -2
- package/dist/esm/errorcodes.js +97 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/modules/Api/Auth.js +3 -3
- package/dist/esm/modules/Api/Info.js +2 -2
- package/dist/esm/modules/AudioStation/{Song/index.js → Song.js} +3 -10
- package/dist/esm/modules/AudioStation/index.js +1 -1
- package/dist/esm/modules/FileStation/File.js +0 -0
- package/dist/{cjs/modules/AudioStation/Song/index.js → esm/modules/FileStation/Info.js} +4 -12
- package/dist/esm/modules/FileStation/List.js +32 -0
- package/dist/esm/modules/FileStation/index.js +11 -0
- package/dist/esm/modules/index.js +11 -3
- package/dist/esm/types/apiInfo.js +42 -0
- package/dist/esm/types/index.js +2 -1
- package/dist/esm/utils.js +6 -0
- package/dist/types/constants.d.ts +3 -2
- package/dist/types/core.d.ts +1 -1
- package/dist/types/errorcodes.d.ts +93 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/modules/AudioStation/{Song/types.d.ts → Song.d.ts} +5 -1
- package/dist/types/modules/FileStation/File.d.ts +0 -0
- package/dist/types/modules/FileStation/Info.d.ts +11 -0
- package/dist/types/modules/FileStation/List.d.ts +59 -0
- package/dist/types/modules/FileStation/index.d.ts +11 -0
- package/dist/types/modules/index.d.ts +4 -0
- package/dist/types/types/apiInfo.d.ts +39 -0
- package/dist/types/types/index.d.ts +2 -1
- package/dist/types/types/{API.d.ts → request.d.ts} +3 -4
- package/dist/types/utils.d.ts +2 -0
- package/package.json +4 -4
- package/dist/cjs/constants.js +0 -7
- package/dist/cjs/core.js +0 -109
- package/dist/cjs/helpers.js +0 -88
- package/dist/cjs/modules/Api/Auth.js +0 -50
- package/dist/cjs/modules/Api/Info.js +0 -32
- package/dist/cjs/modules/Api/index.js +0 -18
- package/dist/cjs/modules/AudioStation/Song/types.js +0 -2
- package/dist/cjs/modules/AudioStation/index.js +0 -8
- package/dist/cjs/modules/index.js +0 -24
- package/dist/cjs/types/API.js +0 -3
- package/dist/cjs/types/index.js +0 -17
- package/dist/cjs/utils.js +0 -19
- package/dist/esm/modules/AudioStation/Song/types.js +0 -1
- package/dist/types/modules/AudioStation/Song/index.d.ts +0 -5
- /package/dist/esm/types/{API.js → request.js} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Synology Api
|
|
2
2
|
|
|
3
3
|
nodejs synology api wrapper
|
|
4
4
|
|
|
@@ -14,9 +14,13 @@ const synologyApi = new SynologyApi(
|
|
|
14
14
|
password: "password",
|
|
15
15
|
);
|
|
16
16
|
|
|
17
|
-
//
|
|
18
|
-
await synologyApi.
|
|
17
|
+
// you can now use the api by calling the methods
|
|
18
|
+
const info = await synologyApi.FileStation.getInfo();
|
|
19
19
|
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
## API
|
|
23
|
+
|
|
24
|
+
### FileStation
|
|
25
|
+
|
|
26
|
+
### AudioStation
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,19 +1,551 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
var __copyProps = (to, from, except, desc) => {
|
|
29
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
30
|
+
for (let key of __getOwnPropNames(from))
|
|
31
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
32
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
33
|
+
}
|
|
34
|
+
return to;
|
|
35
|
+
};
|
|
36
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
37
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
38
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
39
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
40
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
41
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
42
|
+
mod
|
|
43
|
+
));
|
|
44
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
45
|
+
var __async = (__this, __arguments, generator) => {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
var fulfilled = (value) => {
|
|
48
|
+
try {
|
|
49
|
+
step(generator.next(value));
|
|
50
|
+
} catch (e) {
|
|
51
|
+
reject(e);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var rejected = (value) => {
|
|
55
|
+
try {
|
|
56
|
+
step(generator.throw(value));
|
|
57
|
+
} catch (e) {
|
|
58
|
+
reject(e);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
62
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/index.ts
|
|
67
|
+
var index_exports = {};
|
|
68
|
+
__export(index_exports, {
|
|
69
|
+
AudioStationApi: () => AudioStationApi,
|
|
70
|
+
FileStationApi: () => FileStationApi,
|
|
71
|
+
SynologyApi: () => SynologyApi,
|
|
72
|
+
SynologyApiInfo: () => SynologyApiInfo,
|
|
73
|
+
default: () => index_default
|
|
74
|
+
});
|
|
75
|
+
module.exports = __toCommonJS(index_exports);
|
|
76
|
+
|
|
77
|
+
// src/core.ts
|
|
78
|
+
var import_axios4 = __toESM(require("axios"));
|
|
79
|
+
|
|
80
|
+
// src/types/apiInfo.ts
|
|
81
|
+
var SynologyApiInfo = /* @__PURE__ */ ((SynologyApiInfo2) => {
|
|
82
|
+
SynologyApiInfo2["Auth"] = "SYNO.API.Auth";
|
|
83
|
+
SynologyApiInfo2["Info"] = "SYNO.API.Info";
|
|
84
|
+
SynologyApiInfo2["OTP"] = "SYNO.API.OTP";
|
|
85
|
+
return SynologyApiInfo2;
|
|
86
|
+
})(SynologyApiInfo || {});
|
|
87
|
+
var AudioStationApi = /* @__PURE__ */ ((AudioStationApi2) => {
|
|
88
|
+
AudioStationApi2["Song"] = "SYNO.AudioStation.Song";
|
|
89
|
+
AudioStationApi2["Album"] = "SYNO.AudioStation.Album";
|
|
90
|
+
AudioStationApi2["Artist"] = "SYNO.AudioStation.Artist";
|
|
91
|
+
AudioStationApi2["Genre"] = "SYNO.AudioStation.Genre";
|
|
92
|
+
AudioStationApi2["Playlist"] = "SYNO.AudioStation.Playlist";
|
|
93
|
+
AudioStationApi2["Folder"] = "SYNO.AudioStation.Folder";
|
|
94
|
+
AudioStationApi2["Cover"] = "SYNO.AudioStation.Cover";
|
|
95
|
+
AudioStationApi2["Download"] = "SYNO.AudioStation.Download";
|
|
96
|
+
AudioStationApi2["Info"] = "SYNO.AudioStation.Info";
|
|
97
|
+
AudioStationApi2["Lyrics"] = "SYNO.AudioStation.Lyrics";
|
|
98
|
+
AudioStationApi2["LyricsSearch"] = "SYNO.AudioStation.LyricsSearch";
|
|
99
|
+
AudioStationApi2["Radio"] = "SYNO.AudioStation.Radio";
|
|
100
|
+
AudioStationApi2["Stream"] = "SYNO.AudioStation.Stream";
|
|
101
|
+
AudioStationApi2["Tag"] = "SYNO.AudioStation.Tag";
|
|
102
|
+
return AudioStationApi2;
|
|
103
|
+
})(AudioStationApi || {});
|
|
104
|
+
var FileStationApi = /* @__PURE__ */ ((FileStationApi2) => {
|
|
105
|
+
FileStationApi2["File"] = "SYNO.FileStation.File";
|
|
106
|
+
FileStationApi2["Info"] = "SYNO.FileStation.Info";
|
|
107
|
+
FileStationApi2["List"] = "SYNO.FileStation.List";
|
|
108
|
+
FileStationApi2["Quota"] = "SYNO.FileStation.Quota";
|
|
109
|
+
FileStationApi2["Share"] = "SYNO.FileStation.Share";
|
|
110
|
+
FileStationApi2["Thumb"] = "SYNO.FileStation.Thumb";
|
|
111
|
+
FileStationApi2["Upload"] = "SYNO.FileStation.Upload";
|
|
112
|
+
return FileStationApi2;
|
|
113
|
+
})(FileStationApi || {});
|
|
114
|
+
|
|
115
|
+
// src/modules/AudioStation/Song.ts
|
|
116
|
+
function getSongList(params) {
|
|
117
|
+
return __async(this, null, function* () {
|
|
118
|
+
const res = yield this.run("SYNO.AudioStation.Song" /* Song */, {
|
|
119
|
+
params: __spreadValues({
|
|
120
|
+
method: "list",
|
|
121
|
+
library: "all"
|
|
122
|
+
}, params)
|
|
123
|
+
});
|
|
124
|
+
return res.data;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/modules/AudioStation/index.ts
|
|
129
|
+
var AudioStationMethods = {
|
|
130
|
+
getSongList
|
|
131
|
+
};
|
|
132
|
+
var AudioStationKey = "AudioStation";
|
|
133
|
+
|
|
134
|
+
// src/modules/FileStation/Info.ts
|
|
135
|
+
function getInfo() {
|
|
136
|
+
return __async(this, null, function* () {
|
|
137
|
+
const res = yield this.run("SYNO.FileStation.Info" /* Info */, {
|
|
138
|
+
params: {
|
|
139
|
+
method: "get"
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
return res.data;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/utils.ts
|
|
147
|
+
function isHttpUrl(url) {
|
|
148
|
+
return /^https?:\/\//.test(url);
|
|
149
|
+
}
|
|
150
|
+
function isUndfined(value) {
|
|
151
|
+
return value === void 0;
|
|
152
|
+
}
|
|
153
|
+
function getApiKey(apiName) {
|
|
154
|
+
return apiName.split(".")[1];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/modules/FileStation/List.ts
|
|
158
|
+
function getFileList() {
|
|
159
|
+
return __async(this, arguments, function* (params = {}) {
|
|
160
|
+
const { additional = ["real_path", "size", "owner", "time"], filetype = "all" } = params;
|
|
161
|
+
if (isUndfined(params.folder_path)) {
|
|
162
|
+
throw new Error("folder_path is required");
|
|
163
|
+
}
|
|
164
|
+
const res = yield this.run("SYNO.FileStation.List" /* List */, {
|
|
165
|
+
params: __spreadValues({
|
|
166
|
+
method: "list",
|
|
167
|
+
additional: JSON.stringify(additional),
|
|
168
|
+
filetype,
|
|
169
|
+
folder_path: params.folder_path
|
|
170
|
+
}, params)
|
|
171
|
+
});
|
|
172
|
+
return res.data;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function getFileListShare() {
|
|
176
|
+
return __async(this, arguments, function* (params = {}) {
|
|
177
|
+
const { additional = ["real_path", "size", "owner", "time"], onlywritable = false } = params;
|
|
178
|
+
const res = yield this.run("SYNO.FileStation.List" /* List */, {
|
|
179
|
+
params: __spreadValues({
|
|
180
|
+
method: "list_share",
|
|
181
|
+
additional: JSON.stringify(additional),
|
|
182
|
+
onlywritable
|
|
183
|
+
}, params)
|
|
184
|
+
});
|
|
185
|
+
return res.data;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/modules/FileStation/index.ts
|
|
190
|
+
var FileStationMethods = {
|
|
191
|
+
getInfo,
|
|
192
|
+
getFileList,
|
|
193
|
+
getFileListShare
|
|
194
|
+
};
|
|
195
|
+
var FileStationKey = "FileStation";
|
|
196
|
+
|
|
197
|
+
// src/modules/index.ts
|
|
198
|
+
AudioStationKey, FileStationKey;
|
|
199
|
+
var BaseSynologyApi = class {
|
|
200
|
+
constructor() {
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
function methodsBundler(instance, methods) {
|
|
204
|
+
const output = {};
|
|
205
|
+
for (const key in methods) {
|
|
206
|
+
output[key] = methods[key].bind(instance);
|
|
207
|
+
}
|
|
208
|
+
return output;
|
|
209
|
+
}
|
|
210
|
+
Object.defineProperties(BaseSynologyApi.prototype, {
|
|
211
|
+
[FileStationKey]: {
|
|
212
|
+
get() {
|
|
213
|
+
return methodsBundler(this, FileStationMethods);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
[AudioStationKey]: {
|
|
217
|
+
get() {
|
|
218
|
+
return methodsBundler(this, AudioStationMethods);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// src/helpers.ts
|
|
224
|
+
var import_axios = __toESM(require("axios"));
|
|
225
|
+
|
|
226
|
+
// src/constants.ts
|
|
227
|
+
var GLOBAL_QUICK_CONNECT_URL = "https://global.quickconnect.cn/Serv.php";
|
|
228
|
+
var QUICK_CONNECT_PINGPANG_API = "/webman/pingpong.cgi?action=cors&quickconnect=true";
|
|
229
|
+
|
|
230
|
+
// src/helpers.ts
|
|
231
|
+
var getServersFromServerInfo = (serverInfo) => __async(null, null, function* () {
|
|
232
|
+
var _a, _b;
|
|
233
|
+
if (serverInfo.service.relay_ip) {
|
|
234
|
+
const server = `http://${serverInfo.service.relay_ip}:${serverInfo.service.relay_port}`;
|
|
235
|
+
const res = yield pingpang(server);
|
|
236
|
+
if (res) {
|
|
237
|
+
return server;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (serverInfo.server.external.ip) {
|
|
241
|
+
const server = `http://${serverInfo.server.external.ip}:${serverInfo.service.port}`;
|
|
242
|
+
if (yield pingpang(server)) {
|
|
243
|
+
return server;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if ((_a = serverInfo.server.interface) == null ? void 0 : _a[0]) {
|
|
247
|
+
const server = `http://${(_b = serverInfo.server.interface) == null ? void 0 : _b[0].ip}:${serverInfo.service.port}`;
|
|
248
|
+
if (yield pingpang(server)) {
|
|
249
|
+
return server;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
var getServerInfo = (quickConnectId) => __async(null, null, function* () {
|
|
254
|
+
var _a, _b, _c, _d;
|
|
255
|
+
const params = {
|
|
256
|
+
version: 1,
|
|
257
|
+
id: "dsm",
|
|
258
|
+
serverID: quickConnectId,
|
|
259
|
+
get_ca_fingerprints: true,
|
|
260
|
+
command: "get_server_info"
|
|
261
|
+
};
|
|
262
|
+
const serverInfo = yield import_axios.default.post(GLOBAL_QUICK_CONNECT_URL, params);
|
|
263
|
+
if (!((_b = (_a = serverInfo.data) == null ? void 0 : _a.service) == null ? void 0 : _b.relay_ip) && !((_d = (_c = serverInfo.data) == null ? void 0 : _c.service) == null ? void 0 : _d.relay_port)) {
|
|
264
|
+
const relayRequestParams = {
|
|
265
|
+
version: 1,
|
|
266
|
+
id: "dsm",
|
|
267
|
+
serverID: quickConnectId,
|
|
268
|
+
platform: "web",
|
|
269
|
+
command: "request_tunnel"
|
|
270
|
+
};
|
|
271
|
+
const result = yield import_axios.default.post(
|
|
272
|
+
`https://${serverInfo.data.env.control_host}/Serv.php`,
|
|
273
|
+
relayRequestParams
|
|
274
|
+
);
|
|
275
|
+
return getServersFromServerInfo(result.data);
|
|
276
|
+
} else {
|
|
277
|
+
return getServersFromServerInfo(serverInfo.data);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
var pingpang = (server) => __async(null, null, function* () {
|
|
281
|
+
try {
|
|
282
|
+
const result = yield import_axios.default.get(`${server}/${QUICK_CONNECT_PINGPANG_API}`, {
|
|
283
|
+
timeout: 3e3
|
|
284
|
+
});
|
|
285
|
+
if (result.data.success) {
|
|
286
|
+
return true;
|
|
287
|
+
} else {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
} catch (_err) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
// src/modules/Api/Auth.ts
|
|
296
|
+
var import_axios2 = __toESM(require("axios"));
|
|
297
|
+
function login(core) {
|
|
298
|
+
return __async(this, null, function* () {
|
|
299
|
+
const params = {
|
|
300
|
+
api: "SYNO.API.Auth" /* Auth */,
|
|
301
|
+
version: 6,
|
|
302
|
+
method: "login",
|
|
303
|
+
account: core.username,
|
|
304
|
+
passwd: core.password,
|
|
305
|
+
format: "sid"
|
|
306
|
+
};
|
|
307
|
+
const url = `${core.baseUrl}entry.cgi`;
|
|
308
|
+
const result = yield import_axios2.default.get(url, { params });
|
|
309
|
+
if (!result.data.success) {
|
|
310
|
+
throw new Error(result.data.error.message);
|
|
311
|
+
}
|
|
312
|
+
return result.data;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function logout(core) {
|
|
316
|
+
return __async(this, null, function* () {
|
|
317
|
+
const params = {
|
|
318
|
+
api: "SYNO.API.Auth" /* Auth */,
|
|
319
|
+
version: 6,
|
|
320
|
+
method: "logout"
|
|
321
|
+
};
|
|
322
|
+
const url = `${core.baseUrl}entry.cgi`;
|
|
323
|
+
const result = yield import_axios2.default.get(url, { params });
|
|
324
|
+
if (!result.data.success) {
|
|
325
|
+
throw new Error(result.data.error.message);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/modules/Api/Info.ts
|
|
331
|
+
var import_axios3 = __toESM(require("axios"));
|
|
332
|
+
function getApiInfo(core) {
|
|
333
|
+
return __async(this, null, function* () {
|
|
334
|
+
const params = {
|
|
335
|
+
api: "SYNO.API.Info" /* Info */,
|
|
336
|
+
version: 1,
|
|
337
|
+
method: "query"
|
|
338
|
+
};
|
|
339
|
+
const url = `${core.baseUrl}entry.cgi`;
|
|
340
|
+
const result = yield import_axios3.default.get(url, { params });
|
|
341
|
+
if (!result.data.success) {
|
|
342
|
+
throw new Error(result.data.error.message);
|
|
343
|
+
}
|
|
344
|
+
return result.data;
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// src/errorcodes.ts
|
|
349
|
+
var CODE_SUCCESS = 0;
|
|
350
|
+
var CODE_UNKNOWN = 9999;
|
|
351
|
+
var SYNOLOGY_ERROR_CODES = {
|
|
352
|
+
[FileStationKey]: {
|
|
353
|
+
400: "Invalid parameter of file operation",
|
|
354
|
+
401: "Unknown error of file operation",
|
|
355
|
+
402: "System is too busy",
|
|
356
|
+
403: "Invalid user does this file operation",
|
|
357
|
+
404: "Invalid group does this file operation",
|
|
358
|
+
405: "Invalid user and group does this file operation",
|
|
359
|
+
406: "Can't get user/group information from the account server",
|
|
360
|
+
407: "Operation not permitted",
|
|
361
|
+
408: "No such file or directory",
|
|
362
|
+
409: "Non-supported file system",
|
|
363
|
+
410: "Failed to connect internet-based file system (e.g., CIFS)",
|
|
364
|
+
411: "Read-only file system",
|
|
365
|
+
412: "Filename too long in the non-encrypted file system",
|
|
366
|
+
413: "Filename too long in the encrypted file system",
|
|
367
|
+
414: "File already exists",
|
|
368
|
+
415: "Disk quota exceeded",
|
|
369
|
+
416: "No space left on device",
|
|
370
|
+
417: "Input/output error",
|
|
371
|
+
418: "Illegal name or path",
|
|
372
|
+
419: "Illegal file name",
|
|
373
|
+
420: "Illegal file name on FAT file system",
|
|
374
|
+
421: "Device or resource busy",
|
|
375
|
+
599: "No such task of the file operation"
|
|
376
|
+
},
|
|
377
|
+
[AudioStationKey]: {},
|
|
378
|
+
COMMON_CODES: {
|
|
379
|
+
[CODE_SUCCESS]: "Success",
|
|
380
|
+
100: "Unknown error",
|
|
381
|
+
101: "No parameter of API, method or version",
|
|
382
|
+
102: "The requested API does not exist",
|
|
383
|
+
103: "The requested method does not exist",
|
|
384
|
+
104: "The requested version does not support the functionality",
|
|
385
|
+
105: "The logged in session does not have permission",
|
|
386
|
+
106: "Session timeout",
|
|
387
|
+
107: "Session interrupted by duplicated login",
|
|
388
|
+
108: "Failed to upload the file",
|
|
389
|
+
109: "The network connection is unstable or the system is busy",
|
|
390
|
+
110: "The network connection is unstable or the system is busy",
|
|
391
|
+
111: "The network connection is unstable or the system is busy",
|
|
392
|
+
112: "Preserve for other purpose",
|
|
393
|
+
113: "Preserve for other purpose",
|
|
394
|
+
114: "Lost parameters for this API",
|
|
395
|
+
115: "Not allowed to upload a file",
|
|
396
|
+
116: "Not allowed to perform for a demo site",
|
|
397
|
+
117: "The network connection is unstable or the system is busy",
|
|
398
|
+
118: "The network connection is unstable or the system is busy",
|
|
399
|
+
119: "Invalid session / SID not found.",
|
|
400
|
+
// # 120-149 Preserve for other purpose
|
|
401
|
+
120: "Preserve for other purpose",
|
|
402
|
+
121: "Preserve for other purpose",
|
|
403
|
+
122: "Preserve for other purpose",
|
|
404
|
+
123: "Preserve for other purpose",
|
|
405
|
+
124: "Preserve for other purpose",
|
|
406
|
+
125: "Preserve for other purpose",
|
|
407
|
+
126: "Preserve for other purpose",
|
|
408
|
+
127: "Preserve for other purpose",
|
|
409
|
+
128: "Preserve for other purpose",
|
|
410
|
+
129: "Preserve for other purpose",
|
|
411
|
+
130: "Preserve for other purpose",
|
|
412
|
+
131: "Preserve for other purpose",
|
|
413
|
+
132: "Preserve for other purpose",
|
|
414
|
+
133: "Preserve for other purpose",
|
|
415
|
+
134: "Preserve for other purpose",
|
|
416
|
+
135: "Preserve for other purpose",
|
|
417
|
+
136: "Preserve for other purpose",
|
|
418
|
+
137: "Preserve for other purpose",
|
|
419
|
+
138: "Preserve for other purpose",
|
|
420
|
+
139: "Preserve for other purpose",
|
|
421
|
+
140: "Preserve for other purpose",
|
|
422
|
+
141: "Preserve for other purpose",
|
|
423
|
+
142: "Preserve for other purpose",
|
|
424
|
+
143: "Preserve for other purpose",
|
|
425
|
+
144: "Preserve for other purpose",
|
|
426
|
+
145: "Preserve for other purpose",
|
|
427
|
+
146: "Preserve for other purpose",
|
|
428
|
+
147: "Preserve for other purpose",
|
|
429
|
+
148: "Preserve for other purpose",
|
|
430
|
+
149: "Preserve for other purpose",
|
|
431
|
+
150: "Request source IP does not match the login IP",
|
|
432
|
+
160: "Insufficient application privilege",
|
|
433
|
+
[CODE_UNKNOWN]: "Unknown error"
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
var resWithErrorCode = (apiKey, res) => {
|
|
437
|
+
var _a, _b;
|
|
438
|
+
const errorCodes = SYNOLOGY_ERROR_CODES[apiKey];
|
|
439
|
+
const code = (_a = res == null ? void 0 : res.error) == null ? void 0 : _a.code;
|
|
440
|
+
if (isUndfined(code)) return res;
|
|
441
|
+
return __spreadProps(__spreadValues({}, res), {
|
|
442
|
+
error: __spreadProps(__spreadValues({}, res.error), {
|
|
443
|
+
message: ((_b = res == null ? void 0 : res.error) == null ? void 0 : _b.message) || (errorCodes == null ? void 0 : errorCodes[code]) || "Unknown error"
|
|
444
|
+
})
|
|
445
|
+
});
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
// src/core.ts
|
|
449
|
+
var SynologyApi = class extends BaseSynologyApi {
|
|
450
|
+
constructor(options) {
|
|
451
|
+
super();
|
|
452
|
+
this.isConnecting = false;
|
|
453
|
+
this.authInfo = null;
|
|
454
|
+
this.apiInfo = {};
|
|
455
|
+
this.server = options.server;
|
|
456
|
+
this.username = options.username;
|
|
457
|
+
this.password = options.password;
|
|
458
|
+
this.baseUrl = `${this.server}/webapi/`;
|
|
459
|
+
}
|
|
460
|
+
connect() {
|
|
461
|
+
return __async(this, null, function* () {
|
|
462
|
+
if (!isHttpUrl(this.server)) {
|
|
463
|
+
this.server = yield getServerInfo(this.server);
|
|
464
|
+
this.baseUrl = `${this.server}/webapi/`;
|
|
465
|
+
}
|
|
466
|
+
try {
|
|
467
|
+
const result = yield login(this);
|
|
468
|
+
this.authInfo = result.data;
|
|
469
|
+
this.isConnecting = true;
|
|
470
|
+
yield this._getApiInfo();
|
|
471
|
+
return true;
|
|
472
|
+
} catch (err) {
|
|
473
|
+
console.error(err);
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
disconnect() {
|
|
479
|
+
return __async(this, null, function* () {
|
|
480
|
+
try {
|
|
481
|
+
yield logout(this);
|
|
482
|
+
this.authInfo = null;
|
|
483
|
+
this.apiInfo = {};
|
|
484
|
+
this.isConnecting = false;
|
|
485
|
+
return true;
|
|
486
|
+
} catch (err) {
|
|
487
|
+
console.error(err);
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
_getApiInfo() {
|
|
493
|
+
return __async(this, null, function* () {
|
|
494
|
+
try {
|
|
495
|
+
const result = yield getApiInfo(this);
|
|
496
|
+
this.apiInfo = result.data;
|
|
497
|
+
} catch (err) {
|
|
498
|
+
console.error(err);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
hasApi(apiName) {
|
|
503
|
+
if (!this.isConnecting) {
|
|
504
|
+
throw new Error("Not connected");
|
|
505
|
+
}
|
|
506
|
+
return Object.prototype.hasOwnProperty.call(this.apiInfo, apiName);
|
|
507
|
+
}
|
|
508
|
+
run(apiName, options) {
|
|
509
|
+
return __async(this, null, function* () {
|
|
510
|
+
if (!this.isConnecting) {
|
|
511
|
+
const res = yield this.connect();
|
|
512
|
+
if (!res) {
|
|
513
|
+
throw new Error("Not connected");
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (!this.hasApi(apiName)) {
|
|
517
|
+
throw new Error(`${apiName} not found`);
|
|
518
|
+
}
|
|
519
|
+
const { method = "get", params, data, headers } = options;
|
|
520
|
+
const api = this.apiInfo[apiName];
|
|
521
|
+
const url = `${this.baseUrl}${api.path}`;
|
|
522
|
+
const externalParams = __spreadValues({
|
|
523
|
+
api: apiName,
|
|
524
|
+
version: api.maxVersion,
|
|
525
|
+
_sid: this.authInfo.sid
|
|
526
|
+
}, params);
|
|
527
|
+
let result = null;
|
|
528
|
+
if (method === "get") {
|
|
529
|
+
result = yield import_axios4.default.get(url, { params: externalParams, data, headers });
|
|
530
|
+
}
|
|
531
|
+
if (method === "post") {
|
|
532
|
+
result = yield import_axios4.default.post(url, { params: externalParams, data, headers });
|
|
533
|
+
}
|
|
534
|
+
const apiKey = getApiKey(apiName);
|
|
535
|
+
if (!isUndfined(apiKey)) {
|
|
536
|
+
result.data = resWithErrorCode(apiKey, result.data);
|
|
537
|
+
}
|
|
538
|
+
return result;
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
// src/index.ts
|
|
544
|
+
var index_default = SynologyApi;
|
|
545
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
546
|
+
0 && (module.exports = {
|
|
547
|
+
AudioStationApi,
|
|
548
|
+
FileStationApi,
|
|
549
|
+
SynologyApi,
|
|
550
|
+
SynologyApiInfo
|
|
551
|
+
});
|
package/dist/esm/constants.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* synology constants
|
|
3
|
+
*/
|
|
3
4
|
export const GLOBAL_QUICK_CONNECT_URL = "https://global.quickconnect.cn/Serv.php";
|
|
4
5
|
export const QUICK_CONNECT_PINGPANG_API = "/webman/pingpong.cgi?action=cors&quickconnect=true";
|
package/dist/esm/core.js
CHANGED
|
@@ -10,9 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
// reference: https://kb.synology.com/zh-tw/DSM/tutorial/What_websites_does_Synology_NAS_connect_to_when_running_services_or_updating_software
|
|
11
11
|
import axios from "axios";
|
|
12
12
|
import { BaseSynologyApi } from "./modules";
|
|
13
|
-
import { isHttpUrl } from "./utils";
|
|
13
|
+
import { isHttpUrl, getApiKey, isUndfined } from "./utils";
|
|
14
14
|
import { getServerInfo } from "./helpers";
|
|
15
15
|
import { login, logout, getApiInfo } from "./modules/Api";
|
|
16
|
+
import { resWithErrorCode } from "./errorcodes";
|
|
16
17
|
export class SynologyApi extends BaseSynologyApi {
|
|
17
18
|
constructor(options) {
|
|
18
19
|
super();
|
|
@@ -80,7 +81,10 @@ export class SynologyApi extends BaseSynologyApi {
|
|
|
80
81
|
run(apiName, options) {
|
|
81
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
82
83
|
if (!this.isConnecting) {
|
|
83
|
-
|
|
84
|
+
const res = yield this.connect();
|
|
85
|
+
if (!res) {
|
|
86
|
+
throw new Error("Not connected");
|
|
87
|
+
}
|
|
84
88
|
}
|
|
85
89
|
if (!this.hasApi(apiName)) {
|
|
86
90
|
throw new Error(`${apiName} not found`);
|
|
@@ -96,6 +100,11 @@ export class SynologyApi extends BaseSynologyApi {
|
|
|
96
100
|
if (method === "post") {
|
|
97
101
|
result = yield axios.post(url, { params: externalParams, data, headers });
|
|
98
102
|
}
|
|
103
|
+
// match error code msg
|
|
104
|
+
const apiKey = getApiKey(apiName);
|
|
105
|
+
if (!isUndfined(apiKey)) {
|
|
106
|
+
result.data = resWithErrorCode(apiKey, result.data);
|
|
107
|
+
}
|
|
99
108
|
return result;
|
|
100
109
|
});
|
|
101
110
|
}
|