exaroton 1.9.0 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ jobs:
14
14
  - uses: actions/checkout@v3
15
15
  - uses: actions/setup-node@v3
16
16
  with:
17
- node-version: 16
17
+ node-version: 20
18
18
  registry-url: https://registry.npmjs.org/
19
19
  - run: npm install -g npm
20
20
  - run: npm ci
package/README.md CHANGED
@@ -291,6 +291,72 @@ try {
291
291
  }
292
292
  ```
293
293
 
294
+ #### Config files
295
+ Config files are files that contain server configuration and are shown as forms rather than plain text files in the exaroton panel.
296
+ You can get a config file object by using the `getConfig()` method on a file object.
297
+ Whether a file is a config file can be checked using the `isConfigFile` property.
298
+
299
+ ```js
300
+ let file = server.getFile("server.properties");
301
+ let config = file.getConfig();
302
+ ```
303
+
304
+ ##### Get config file options
305
+ ```js
306
+ let options = await config.getOptions();
307
+ for(let [key, option] of options) {
308
+ console.log(key, option.getValue());
309
+ }
310
+ ```
311
+
312
+ ##### Update config file options
313
+ ```js
314
+ let options = await config.getOptions();
315
+
316
+ options.get("max-players").setValue(26);
317
+ options.get("pvp").setValue(false);
318
+
319
+ await config.save();
320
+ ```
321
+
322
+ Options of type `select` or `multiselect` have a list of possible values.
323
+ ```js
324
+ let options = await config.getOptions();
325
+ console.log(options.get("difficulty").getOptions());
326
+ ```
327
+
328
+ #### Credit pools
329
+ Credit pools allow sharing the costs of a server between multiple users.
330
+
331
+ ##### List credit pools
332
+ ```js
333
+ let pools = await client.getPools();
334
+ console.log(pools);
335
+ ```
336
+
337
+ ##### Create a pool object by ID
338
+ ```js
339
+ let server = client.pool(id);
340
+ ```
341
+
342
+ ##### Get pool information
343
+ ```js
344
+ await pool.get();
345
+ console.log(pool.name + ": " + pool.credits);
346
+ ```
347
+
348
+ ##### Get pool members
349
+ ```js
350
+ let members = await pool.getMembers();
351
+ console.log(members);
352
+ ```
353
+
354
+ ##### Get pool servers
355
+ ```js
356
+ let servers = await pool.getServers();
357
+ console.log(servers);
358
+ ```
359
+
294
360
  ### Websocket API
295
361
  The websocket API allows a constant connection to our websocket service to receive
296
362
  events in real time without polling (e.g. trying to get the server status every few seconds).
@@ -372,4 +438,4 @@ You can unsubscribe from one, multiple or all streams using the `server.unsubscr
372
438
  server.unsubscribe("console");
373
439
  server.unsubscribe(["tick", "heap"]);
374
440
  server.unsubscribe(); // this disconnects the websocket connection
375
- ```
441
+ ```
package/index.js CHANGED
@@ -4,5 +4,8 @@ module.exports = {
4
4
  Software: require('./src/Server/Software'),
5
5
  ServerStatus: require('./src/Server/ServerStatus'),
6
6
  Request: require('./src/Request/Request'),
7
- Response: require('./src/Response/Response')
8
- }
7
+ Response: require('./src/Response/Response'),
8
+ ConfigOptionType: require('./src/Server/Config/ConfigOptionType'),
9
+ Pool: require('./src/Billing/Pool/Pool'),
10
+ PoolMember: require('./src/Billing/Pool/PoolMember')
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "exaroton",
3
- "version": "1.9.0",
3
+ "version": "1.11.1",
4
4
  "description": "exaroton API client",
5
5
  "homepage": "https://exaroton.com",
6
6
  "main": "index.js",
@@ -0,0 +1,137 @@
1
+ const GetPoolRequest = require("../../Request/Billing/Pool/GetPoolRequest.js");
2
+ const GetPoolMembersRequest = require("../../Request/Billing/Pool/GetPoolMembersRequest.js");
3
+ const GetPoolServersRequest = require("../../Request/Billing/Pool/GetPoolServersRequest.js");
4
+
5
+ class Pool {
6
+ /**
7
+ * @type {Client}
8
+ * @private
9
+ */
10
+ #client;
11
+
12
+ /**
13
+ * Pool ID
14
+ *
15
+ * @type {string}
16
+ */
17
+ id;
18
+
19
+ /**
20
+ * Pool name
21
+ *
22
+ * @type {string}
23
+ */
24
+ name;
25
+
26
+ /**
27
+ * Pool credit balance
28
+ *
29
+ * @type {number}
30
+ */
31
+ credits;
32
+
33
+ /**
34
+ * Pool server count
35
+ *
36
+ * @type {number}
37
+ */
38
+ servers;
39
+
40
+ /**
41
+ * Pool owner ID
42
+ *
43
+ * @type {string}
44
+ */
45
+ owner;
46
+
47
+ /**
48
+ * Is pool owner
49
+ *
50
+ * @type {boolean}
51
+ */
52
+ isOwner;
53
+
54
+ /**
55
+ * Pool member count
56
+ *
57
+ * @type {number}
58
+ */
59
+ members;
60
+
61
+ /**
62
+ * Share of this pool owned by the current account
63
+ *
64
+ * @type {number}
65
+ */
66
+ ownShare;
67
+
68
+ /**
69
+ * Credits in this pool owned by the current account
70
+ *
71
+ * @type {number}
72
+ */
73
+ ownCredits;
74
+
75
+ /**
76
+ * Pool constructor
77
+ *
78
+ * @param {Client} client
79
+ * @param {string} id
80
+ */
81
+ constructor(client, id) {
82
+ this.#client = client;
83
+ this.id = id;
84
+ }
85
+
86
+ /**
87
+ * @param {{}} poolObject
88
+ * @return {this}
89
+ */
90
+ setFromObject(poolObject) {
91
+ this.id = typeof poolObject.id !== "undefined" ? poolObject.id : null;
92
+ this.name = typeof poolObject.name !== "undefined" ? poolObject.name : null;
93
+ this.credits = typeof poolObject.credits !== "undefined" ? poolObject.credits : null;
94
+ this.servers = typeof poolObject.servers !== "undefined" ? poolObject.servers : null;
95
+ this.owner = typeof poolObject.owner !== "undefined" ? poolObject.owner : null;
96
+ this.isOwner = typeof poolObject.isOwner !== "undefined" ? poolObject.isOwner : null;
97
+ this.members = typeof poolObject.members !== "undefined" ? poolObject.members : null;
98
+ this.ownShare = typeof poolObject.ownShare !== "undefined" ? poolObject.ownShare : null;
99
+ this.ownCredits = typeof poolObject.ownCredits !== "undefined" ? poolObject.ownCredits : null;
100
+
101
+ return this;
102
+ }
103
+
104
+ /**
105
+ * Get credit pool info
106
+ *
107
+ * @return {this}
108
+ * @throws {RequestError}
109
+ */
110
+ async get() {
111
+ let response = await this.#client.request(new GetPoolRequest(this.id));
112
+ this.setFromObject(response.getData());
113
+ return this;
114
+ }
115
+
116
+ /**
117
+ * Get pool members
118
+ *
119
+ * @return {Promise<PoolMember[]>}
120
+ */
121
+ async getMembers() {
122
+ let response = await this.#client.request(new GetPoolMembersRequest(this.id));
123
+ return response.getData();
124
+ }
125
+
126
+ /**
127
+ * Get pool servers
128
+ *
129
+ * @return {Promise<Server[]>}
130
+ */
131
+ async getServers() {
132
+ let response = await this.#client.request(new GetPoolServersRequest(this.id));
133
+ return response.getData();
134
+ }
135
+ }
136
+
137
+ module.exports = Pool;
@@ -0,0 +1,52 @@
1
+
2
+ class PoolMember {
3
+ /**
4
+ * Pool member account ID
5
+ *
6
+ * @type {string}
7
+ */
8
+ account;
9
+
10
+ /**
11
+ * Pool member name
12
+ *
13
+ * @type {string}
14
+ */
15
+ name;
16
+
17
+ /**
18
+ * Pool member share
19
+ *
20
+ * @type {number}
21
+ */
22
+ share;
23
+
24
+ /**
25
+ * Pool member credits
26
+ *
27
+ * @type {number}
28
+ */
29
+ credits;
30
+
31
+ /**
32
+ * Is pool owner
33
+ *
34
+ * @type {boolean}
35
+ */
36
+ isOwner;
37
+
38
+ /**
39
+ * Pool member constructor
40
+ *
41
+ * @param {{}} poolMemberObject
42
+ */
43
+ constructor(poolMemberObject) {
44
+ this.account = typeof poolMemberObject.account !== "undefined" ? poolMemberObject.account : null;
45
+ this.name = typeof poolMemberObject.name !== "undefined" ? poolMemberObject.name : null;
46
+ this.share = typeof poolMemberObject.share !== "undefined" ? poolMemberObject.share : null;
47
+ this.credits = typeof poolMemberObject.credits !== "undefined" ? poolMemberObject.credits : null;
48
+ this.isOwner = typeof poolMemberObject.isOwner !== "undefined" ? poolMemberObject.isOwner : null;
49
+ }
50
+ }
51
+
52
+ module.exports = PoolMember;
package/src/Client.js CHANGED
@@ -6,8 +6,10 @@ const Account = require('./Account/Account');
6
6
  const RequestStatusError = require('./Error/RequestStatusError');
7
7
  const RequestBodyError = require('./Error/RequestBodyError');
8
8
  const GetServersRequest = require('./Request/GetServersRequest');
9
+ const GetPoolsRequest = require('./Request/Billing/Pool/GetPoolsRequest');
9
10
 
10
11
  const packageConfig = require('../package.json');
12
+ const Pool = require("./Billing/Pool/Pool.js");
11
13
 
12
14
  class Client {
13
15
  /**
@@ -175,6 +177,16 @@ class Client {
175
177
  return (await this.request(new GetServersRequest)).getData();
176
178
  }
177
179
 
180
+ /**
181
+ * Get a list of all credit pools
182
+ *
183
+ * @return {Promise<Pool[]>}
184
+ * @throws {RequestError}
185
+ */
186
+ async getPools() {
187
+ return (await this.request(new GetPoolsRequest)).getData();
188
+ }
189
+
178
190
  /**
179
191
  * Get account info for the current account
180
192
  *
@@ -194,6 +206,16 @@ class Client {
194
206
  server(id) {
195
207
  return new Server(this, id);
196
208
  }
209
+
210
+ /**
211
+ * Initialize a new pool object
212
+ *
213
+ * @param {string} id
214
+ * @return {Pool}
215
+ */
216
+ pool(id) {
217
+ return new Pool(this, id);
218
+ }
197
219
  }
198
220
 
199
- module.exports = Client;
221
+ module.exports = Client;
@@ -0,0 +1,9 @@
1
+ const PoolRequest = require("./PoolRequest.js");
2
+ const PoolMembersResponse = require("../../../Response/PoolMembersResponse.js");
3
+
4
+ class GetPoolMembersRequest extends PoolRequest {
5
+ endpoint = "billing/pools/{id}/members";
6
+ responseClass = PoolMembersResponse;
7
+ }
8
+
9
+ module.exports = GetPoolMembersRequest;
@@ -0,0 +1,7 @@
1
+ const PoolRequest = require("./PoolRequest.js");
2
+
3
+ class GetPoolRequest extends PoolRequest {
4
+ endpoint = "billing/pools/{id}";
5
+ }
6
+
7
+ module.exports = GetPoolRequest;
@@ -0,0 +1,9 @@
1
+ const PoolRequest = require("./PoolRequest.js");
2
+ const ServersResponse = require("../../../Response/ServersResponse.js");
3
+
4
+ class GetPoolServersRequest extends PoolRequest {
5
+ endpoint = "billing/pools/{id}/servers";
6
+ responseClass = ServersResponse;
7
+ }
8
+
9
+ module.exports = GetPoolServersRequest;
@@ -0,0 +1,9 @@
1
+ const Request = require('../../Request');
2
+ const PoolsResponse = require("../../../Response/PoolsResponse.js");
3
+
4
+ class GetPoolsRequest extends Request {
5
+ endpoint = "billing/pools";
6
+ responseClass = PoolsResponse;
7
+ }
8
+
9
+ module.exports = GetPoolsRequest;
@@ -0,0 +1,15 @@
1
+ const Request = require('../../Request.js');
2
+
3
+ class PoolRequest extends Request {
4
+ /**
5
+ * Pool request constructor
6
+ *
7
+ * @param {string} id
8
+ */
9
+ constructor(id) {
10
+ super();
11
+ this.setParameter("id", id);
12
+ }
13
+ }
14
+
15
+ module.exports = PoolRequest;
@@ -0,0 +1,7 @@
1
+ const FileRequest = require("../FileRequest");
2
+
3
+ class GetConfigFileOptionsRequest extends FileRequest {
4
+ endpoint = "servers/{id}/files/config/{path}";
5
+ }
6
+
7
+ module.exports = GetConfigFileOptionsRequest;
@@ -0,0 +1,21 @@
1
+ const FileRequest = require("../FileRequest");
2
+
3
+ class UpdateConfigFileOptionsRequest extends FileRequest {
4
+ endpoint = "servers/{id}/files/config/{path}";
5
+ method = "POST";
6
+
7
+ /**
8
+ * UpdateConfigFileOptionsRequest constructor
9
+ *
10
+ * @param {string} id
11
+ * @param {string} path
12
+ * @param {Object.<string, string|number|boolean|string[]>} options
13
+ */
14
+ constructor(id, path, options) {
15
+ super(id, path);
16
+
17
+ this.data = options;
18
+ }
19
+ }
20
+
21
+ module.exports = UpdateConfigFileOptionsRequest;
@@ -0,0 +1,44 @@
1
+ const Response = require('./Response');
2
+
3
+ /**
4
+ * @abstract
5
+ */
6
+ class ArrayResponse extends Response {
7
+ /**
8
+ * @type {*[]}
9
+ */
10
+ items = [];
11
+
12
+ /**
13
+ * @inheritDoc
14
+ */
15
+ setBody(body) {
16
+ super.setBody(body);
17
+
18
+ if (!Array.isArray(body.data)) {
19
+ return;
20
+ }
21
+
22
+ for (let object of body.data) {
23
+ this.items.push(this.handleItem(object));
24
+ }
25
+ }
26
+
27
+ /**
28
+ * @param {*} item
29
+ * @return {*}
30
+ * @abstract
31
+ */
32
+ handleItem(item) {
33
+
34
+ }
35
+
36
+ /**
37
+ * @inheritDoc
38
+ */
39
+ getData() {
40
+ return this.items;
41
+ }
42
+ }
43
+
44
+ module.exports = ArrayResponse;
@@ -1,32 +1,12 @@
1
1
  const PlayerList = require('../Server/PlayerList');
2
- const Response = require('./Response');
3
-
4
- class PlayerListsResponse extends Response {
5
- /**
6
- * @type {PlayerList[]}
7
- */
8
- lists = [];
9
-
10
- /**
11
- * @inheritDoc
12
- */
13
- setBody(body) {
14
- super.setBody(body);
15
-
16
- if (!Array.isArray(body.data)) {
17
- return;
18
- }
19
-
20
- for (let playerListName of body.data) {
21
- this.lists.push(new PlayerList(playerListName).setClient(this.request.client));
22
- }
23
- }
2
+ const ArrayResponse = require("./ArrayResponse.js");
24
3
 
4
+ class PlayerListsResponse extends ArrayResponse {
25
5
  /**
26
6
  * @inheritDoc
27
7
  */
28
- getData() {
29
- return this.lists;
8
+ handleItem(item) {
9
+ return new PlayerList(item).setClient(this.request.client);
30
10
  }
31
11
  }
32
- module.exports = PlayerListsResponse;
12
+ module.exports = PlayerListsResponse;
@@ -0,0 +1,13 @@
1
+ const ArrayResponse = require("./ArrayResponse.js");
2
+ const PoolMember = require("../Billing/Pool/PoolMember.js");
3
+
4
+ class PoolMembersResponse extends ArrayResponse {
5
+ /**
6
+ * @inheritDoc
7
+ */
8
+ handleItem(item) {
9
+ return new PoolMember(item);
10
+ }
11
+ }
12
+
13
+ module.exports = PoolMembersResponse;
@@ -0,0 +1,13 @@
1
+ const Pool = require('../Billing/Pool/Pool.js');
2
+ const ArrayResponse = require("./ArrayResponse.js");
3
+
4
+ class PoolsResponse extends ArrayResponse {
5
+ /**
6
+ * @inheritDoc
7
+ */
8
+ handleItem(item) {
9
+ return new Pool(this.request.client, item.id).setFromObject(item);
10
+ }
11
+ }
12
+
13
+ module.exports = PoolsResponse;
@@ -1,33 +1,13 @@
1
- const Response = require('./Response');
2
1
  const Server = require('../Server/Server');
2
+ const ArrayResponse = require("./ArrayResponse.js");
3
3
 
4
- class ServersResponse extends Response {
5
- /**
6
- * @type {Server[]}
7
- */
8
- servers = [];
9
-
10
- /**
11
- * @inheritDoc
12
- */
13
- setBody(body) {
14
- super.setBody(body);
15
-
16
- if (!Array.isArray(body.data)) {
17
- return;
18
- }
19
-
20
- for (let serverObject of body.data) {
21
- this.servers.push(new Server(this.request.client, serverObject.id).setFromObject(serverObject));
22
- }
23
- }
24
-
4
+ class ServersResponse extends ArrayResponse {
25
5
  /**
26
6
  * @inheritDoc
27
7
  */
28
- getData() {
29
- return this.servers;
8
+ handleItem(item) {
9
+ return new Server(this.request.client, item.id).setFromObject(item);
30
10
  }
31
11
  }
32
12
 
33
- module.exports = ServersResponse;
13
+ module.exports = ServersResponse;
@@ -0,0 +1,115 @@
1
+ const GetConfigFileOptionsRequest = require("../../Request/Server/Files/Config/GetConfigFileOptionsRequest");
2
+ const UpdateConfigFileOptionsRequest = require("../../Request/Server/Files/Config/UpdateConfigFileOptionsRequest");
3
+ const ConfigOption = require("./ConfigOption");
4
+
5
+ class Config {
6
+ /**
7
+ * @type {File}
8
+ */
9
+ #file;
10
+
11
+ /**
12
+ * @type {null|Map<string, ConfigOption>}
13
+ */
14
+ #options = null;
15
+
16
+ /**
17
+ * @type {null|Map<string, ConfigOptionValue>}
18
+ */
19
+ #originalValues = null;
20
+
21
+ /**
22
+ * @param {File} file
23
+ */
24
+ constructor(file) {
25
+ this.#file = file;
26
+ }
27
+
28
+ /**
29
+ * @param {Object} object
30
+ * @return {this}
31
+ */
32
+ applyData(object) {
33
+ this.#options = new Map();
34
+ this.#originalValues = new Map();
35
+
36
+ if (!Array.isArray(object)) {
37
+ return this;
38
+ }
39
+
40
+ for (const option of object) {
41
+ if (typeof option !== "object") {
42
+ continue;
43
+ }
44
+
45
+ let {key, label, type, value, options} = option;
46
+ if (typeof key !== "string" || typeof label !== "string" || typeof type !== "string" || options && !Array.isArray(options)) {
47
+ continue;
48
+ }
49
+
50
+ this.#options.set(key, new ConfigOption(key, label, type, value, options));
51
+ this.#originalValues.set(key, value);
52
+ }
53
+ return this;
54
+ }
55
+
56
+ /**
57
+ * @return {Promise<this>}
58
+ */
59
+ async #loadOptions() {
60
+ const response = await this.#file.getClient().request(new GetConfigFileOptionsRequest(this.#file.getServer().id, this.#file.path));
61
+ this.applyData(response.getData());
62
+ return this;
63
+ }
64
+
65
+ /**
66
+ * @param {boolean} update
67
+ * @return {Promise<Map<string, ConfigOption>>}
68
+ */
69
+ async getOptions(update = false) {
70
+ if (update || this.#options === null) {
71
+ await this.#loadOptions();
72
+ }
73
+ return this.#options;
74
+ }
75
+
76
+ /**
77
+ * @param {string} key
78
+ * @return {Promise<ConfigOption|null>}
79
+ */
80
+ async getOption(key) {
81
+ const options = await this.getOptions();
82
+ return options.get(key) ?? null;
83
+ }
84
+
85
+ /**
86
+ * Save all changes made to this config file
87
+ *
88
+ * @return {Promise<Response|null>} null if no changes were made
89
+ */
90
+ async save() {
91
+ let updated = false;
92
+ let changed = {};
93
+ for (let [key, option] of this.#options) {
94
+ if (option.getValue() !== this.#originalValues.get(key)) {
95
+ updated = true;
96
+ changed[key] = option.getValue();
97
+ }
98
+ }
99
+
100
+ if (!updated) {
101
+ return null;
102
+ }
103
+
104
+ let response = await this.#file.getClient().request(
105
+ new UpdateConfigFileOptionsRequest(this.#file.getServer().id, this.#file.path, changed));
106
+
107
+ for (let [key, value] of Object.entries(changed)) {
108
+ this.#originalValues.set(key, value);
109
+ }
110
+
111
+ return response;
112
+ }
113
+ }
114
+
115
+ module.exports = Config;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @typedef {string|number|boolean|string[]} ConfigOptionValue
3
+ */
4
+
5
+ class ConfigOption {
6
+ /**
7
+ * Key of this config option
8
+ *
9
+ * @type {string}
10
+ */
11
+ #key;
12
+
13
+ /**
14
+ * Label of this config option
15
+ *
16
+ * @type {string}
17
+ */
18
+ #label;
19
+
20
+ /**
21
+ * Option type
22
+ *
23
+ * @type {string}
24
+ */
25
+ #type;
26
+
27
+ /**
28
+ * Current option value
29
+ *
30
+ * @type {ConfigOptionValue}
31
+ */
32
+ #value;
33
+
34
+ /**
35
+ * Available options for select/multiselect
36
+ *
37
+ * @type {string[]|null}
38
+ */
39
+ #options;
40
+
41
+ /**
42
+ * ConfigOption constructor
43
+ *
44
+ * @param {string} key
45
+ * @param {string} label
46
+ * @param {string} type
47
+ * @param {ConfigOptionValue} value
48
+ * @param {string[]|null} options
49
+ */
50
+ constructor(key, label, type, value, options = null) {
51
+ this.#key = key;
52
+ this.#label = label;
53
+ this.#type = type;
54
+ this.#value = value;
55
+ this.#options = options;
56
+ }
57
+
58
+ /**
59
+ * @return {string}
60
+ */
61
+ getKey() {
62
+ return this.#key;
63
+ }
64
+
65
+ /**
66
+ * @return {string}
67
+ */
68
+ getLabel() {
69
+ return this.#label;
70
+ }
71
+
72
+ /**
73
+ * @return {string}
74
+ */
75
+ getType() {
76
+ return this.#type;
77
+ }
78
+
79
+ /**
80
+ * @return {ConfigOptionValue}
81
+ */
82
+ getValue() {
83
+ return this.#value;
84
+ }
85
+
86
+ /**
87
+ * @param {ConfigOptionValue} value
88
+ * @return {ConfigOption}
89
+ */
90
+ setValue(value) {
91
+ this.#value = value;
92
+ return this;
93
+ }
94
+
95
+ /**
96
+ * @return {string[]|null}
97
+ */
98
+ getOptions() {
99
+ return this.#options;
100
+ }
101
+ }
102
+
103
+ module.exports = ConfigOption;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @enum {string}
3
+ */
4
+ class ConfigOptionType {
5
+ static STRING = "string";
6
+ static INTEGER = "number";
7
+ static FLOAT = "float";
8
+ static BOOLEAN = "boolean";
9
+ static MULTI_SELECT = "multiselect";
10
+ static SELECT = "select";
11
+ }
12
+
13
+ module.exports = ConfigOptionType;
@@ -3,6 +3,7 @@ const GetFileDataRequest = require("../Request/Server/Files/GetFileDataRequest")
3
3
  const PutFileDataRequest = require("../Request/Server/Files/PutFileDataRequest");
4
4
  const DeleteFileDataRequest = require("../Request/Server/Files/DeleteFileDataRequest");
5
5
  const CreateDirectoryRequest = require("../Request/Server/Files/CreateDirectoryRequest");
6
+ const Config = require("./Config/Config");
6
7
 
7
8
  class File {
8
9
  /**
@@ -60,15 +61,20 @@ class File {
60
61
  children = null;
61
62
 
62
63
  /**
63
- * @type {{Server}}
64
+ * @type {Server}
64
65
  */
65
66
  #server;
66
67
 
67
68
  /**
68
- * @type {{Client}}
69
+ * @type {Client}
69
70
  */
70
71
  #client;
71
72
 
73
+ /**
74
+ * @type {Config|null}
75
+ */
76
+ #config = null;
77
+
72
78
  /**
73
79
  * @param {string|null} path
74
80
  */
@@ -113,7 +119,7 @@ class File {
113
119
  /**
114
120
  * Set the server
115
121
  *
116
- * @param server
122
+ * @param {Server} server
117
123
  * @returns {this}
118
124
  */
119
125
  setServer(server) {
@@ -129,7 +135,7 @@ class File {
129
135
  /**
130
136
  * Set the API client
131
137
  *
132
- * @param client
138
+ * @param {Client} client
133
139
  * @returns {this}
134
140
  */
135
141
  setClient(client) {
@@ -142,6 +148,20 @@ class File {
142
148
  return this;
143
149
  }
144
150
 
151
+ /**
152
+ * @return {Client}
153
+ */
154
+ getClient() {
155
+ return this.#client;
156
+ }
157
+
158
+ /**
159
+ * @return {Server}
160
+ */
161
+ getServer() {
162
+ return this.#server;
163
+ }
164
+
145
165
  /**
146
166
  * Get file information from the API
147
167
  *
@@ -251,6 +271,19 @@ class File {
251
271
 
252
272
  return this.children;
253
273
  }
274
+
275
+ /**
276
+ * Get Config object for this file
277
+ * Only available if the file is a config file
278
+ *
279
+ * @return {Config}
280
+ */
281
+ getConfig() {
282
+ if (this.#config === null) {
283
+ this.#config = new Config(this);
284
+ }
285
+ return this.#config;
286
+ }
254
287
  }
255
288
 
256
- module.exports = File;
289
+ module.exports = File;