├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── custom.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ └── workflow.yml
├── .gitignore
├── .npmignore
├── .prettierignore
├── .prettierrc
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── package.json
├── src
├── application
│ ├── index.ts
│ ├── interfaces
│ │ ├── Allocation.ts
│ │ ├── Database.ts
│ │ ├── Egg.ts
│ │ ├── Location.ts
│ │ ├── Nest.ts
│ │ ├── Node.ts
│ │ ├── Server.ts
│ │ └── User.ts
│ └── methods
│ │ ├── allocation.ts
│ │ ├── database.ts
│ │ ├── location.ts
│ │ ├── nest.ts
│ │ ├── node.ts
│ │ ├── server.ts
│ │ └── user.ts
├── client
│ ├── Websocket.ts
│ ├── index.ts
│ ├── interfaces
│ │ ├── Allocation.ts
│ │ ├── ApiKey.ts
│ │ ├── Backups.ts
│ │ ├── Database.ts
│ │ ├── Permissions.ts
│ │ ├── Schedule.ts
│ │ ├── Server.ts
│ │ ├── ServerFile.ts
│ │ ├── ServerResources.ts
│ │ ├── SubUser.ts
│ │ ├── User.ts
│ │ └── WebsocketAuthData.ts
│ └── methods
│ │ ├── account.ts
│ │ ├── backups.ts
│ │ ├── console.ts
│ │ ├── database.ts
│ │ ├── file.ts
│ │ ├── network.ts
│ │ ├── schedule.ts
│ │ ├── server.ts
│ │ ├── settings.ts
│ │ └── subUser.ts
├── index.ts
└── modules
│ ├── Error.ts
│ ├── Functions.ts
│ ├── Request.ts
│ └── Socket.ts
├── tsconfig.json
├── tsdoc.json
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const prettierOptions = JSON.parse(
5 | fs.readFileSync(path.resolve(__dirname, '.prettierrc'), 'utf8')
6 | );
7 |
8 | /** @type {import("@types/eslint").Linter.Config} */
9 | module.exports = {
10 | env: {
11 | es2022: true,
12 | node: true
13 | },
14 | extends: [
15 | 'eslint:recommended',
16 | 'plugin:@typescript-eslint/recommended',
17 | 'plugin:prettier/recommended'
18 | ],
19 | parser: '@typescript-eslint/parser',
20 | parserOptions: {
21 | ecmaVersion: 'latest',
22 | sourceType: 'module'
23 | },
24 | plugins: ['@typescript-eslint', 'prettier', 'eslint-plugin-tsdoc'],
25 | ignorePatterns: ['dist', '.eslintrc.js'],
26 | rules: {
27 | 'prettier/prettier': ['error', prettierOptions],
28 | 'tsdoc/syntax': 'warn'
29 | },
30 | overrides: [
31 | {
32 | files: ['**/*.ts'],
33 | rules: { 'prettier/prettier': ['error', prettierOptions] }
34 | }
35 | ]
36 | };
37 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Additional context**
27 | Add any other context about the problem here.
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/custom.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Custom issue template
3 | about: Describe this issue template's purpose here.
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: 'npm'
4 | directory: '/'
5 | schedule:
6 | interval: 'weekly'
7 | allow:
8 | - dependency-type: 'production' # Only allow to update production deps
9 |
--------------------------------------------------------------------------------
/.github/workflows/workflow.yml:
--------------------------------------------------------------------------------
1 | name: Node.js Package
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | - next
8 |
9 | jobs:
10 | release:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v3
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v3
17 | with:
18 | node-version: 18
19 | - name: Install dependencies
20 | uses: bahmutov/npm-install@v1
21 | - name: BuildDocs
22 | if: github.ref == 'refs/heads/master'
23 | run: yarn docs:build
24 | - name: Deploy Docs
25 | if: github.ref == 'refs/heads/master'
26 | uses: JamesIves/github-pages-deploy-action@4.1.7
27 | with:
28 | branch: gh-pages
29 | folder: docs
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | docs
4 | test.ts
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test.js
2 | test.d.ts
3 | .eslintrc.js
4 | .prettierignore
5 | .prettierrc
6 | tsdoc.json
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
2 | docs
3 | node_modules
4 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "tabWidth": 2,
4 | "quoteProps": "consistent",
5 | "arrowParens": "always",
6 | "trailingComma": "none"
7 | }
8 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at linas.alexx@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Feel free to contribute to the project by cloning the repository and sending a pull request.
4 |
5 | As always, make sure to state the changes in the title and comment them in description of the PR.
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Linux123123
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSPteroAPI
2 |
3 | [](https://github.com/Linux123123/JSPteroAPI/blob/main/LICENSE)
4 | 
5 | [](https://github.com/Linux123123/JSPteroAPI/issues)
6 | [](https://github.com/Linux123123/JSPteroAPI/pulls)
7 |
8 | [](https://npmjs.com/package/jspteroapi)
9 |
10 |
A simple Pterodactyl API library using undici (written in typescript)
11 |
12 | Uses only 2 dependencies:
13 |
14 | 
15 | 
16 |
17 |
18 | # To install:
19 |
20 | Install from the command line:
21 |
22 | **Npm**
23 |
24 | `npm install jspteroapi`
25 |
26 | **Yarn**
27 |
28 | `yarn add jspteroapi`
29 |
30 | Then include it in your application:
31 |
32 | ```javascript
33 | const node = require('jspteroapi');
34 | const application = new node.Application('HOST', 'TOKEN'); // for application API
35 | const client = new node.Client('HOST', 'TOKEN'); // for Client API
36 | ```
37 |
38 | # How to use
39 |
40 | You can use any application funtion you want:
41 |
42 | ```javascript
43 | application.function(parameters).then((response) => {
44 | // response
45 | });
46 | ```
47 |
48 | or using async / await
49 |
50 | ```javascript
51 | const res = await application.function(parameters);
52 | ```
53 |
54 | # Documentation
55 |
56 |
57 |
58 |
59 | # Versions
60 |
61 | **How versions work:**
62 |
63 | - Panel major version
64 | - The second number is the function release.
65 | - The third number is the bug fix release.
66 |
67 | # Disclaimer
68 |
69 | I am not responsible for any damages that you cause to your servers/nodes by using **this API**.
70 |
71 | **Remember: This API can potentially be dangerous with the ability to Delete Servers/Nodes at an instant!**
72 |
73 | # Contributors
74 |
75 | Created and maintained by [Linux123123](https://github.com/linux123123)
76 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jspteroapi",
3 | "version": "1.11.4",
4 | "description": "A pterodactyl v1 api using undici",
5 | "main": "dist/index.js",
6 | "types": "dist/index.d.ts",
7 | "engines": {
8 | "node": ">=16.8"
9 | },
10 | "engineStrict": true,
11 | "scripts": {
12 | "dev": "tsc-watch --onCompilationComplete \"node --use-openssl-ca dist/test.js\"",
13 | "build": "rimraf dist/* && tsc",
14 | "lint": "eslint \"src/**\"",
15 | "docs:build": "typedoc --categorizeByGroup --defaultCategory Types --excludeInternal --name JSPteroAPI && echo 'User-agent: *\nDisallow: /' > docs/robots.txt",
16 | "release": "yarn build && np"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/Linux123123/JSPteroAPI.git"
21 | },
22 | "keywords": [
23 | "Pterodactyl",
24 | "API",
25 | "undici",
26 | "node-js",
27 | "js",
28 | "ptero-api",
29 | "ptero",
30 | "pterodactyl-api",
31 | "API client"
32 | ],
33 | "author": "Linux123123",
34 | "license": "MIT",
35 | "files": [
36 | "dist/*"
37 | ],
38 | "bugs": {
39 | "url": "https://github.com/Linux123123/JSPteroAPI/issues"
40 | },
41 | "homepage": "https://jspteroapi.linux123123.com",
42 | "dependencies": {
43 | "undici": "^6.6.2",
44 | "ws": "^8.12.0"
45 | },
46 | "devDependencies": {
47 | "@microsoft/tsdoc-config": "^0.16.2",
48 | "@types/node": "^18.13.0",
49 | "@types/ws": "^8.5.4",
50 | "@typescript-eslint/eslint-plugin": "^5.51.0",
51 | "@typescript-eslint/parser": "^5.51.0",
52 | "eslint": "^8.33.0",
53 | "eslint-config-prettier": "^8.6.0",
54 | "eslint-plugin-prettier": "^4.2.1",
55 | "eslint-plugin-tsdoc": "^0.2.17",
56 | "prettier": "^2.8.4",
57 | "rimraf": "^4.1.2",
58 | "tsc-watch": "^6.0.0",
59 | "typedoc": "^0.23.24",
60 | "typescript": "^4.9.5"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/application/index.ts:
--------------------------------------------------------------------------------
1 | import { Request } from '../modules/Request';
2 | import { allocationMethods } from './methods/allocation';
3 | import { databaseMethods } from './methods/database';
4 | import { nestMethods } from './methods/nest';
5 | import { nodeMethods } from './methods/node';
6 | import { serverMethods } from './methods/server';
7 | import { userMethods } from './methods/user';
8 | import { locationMethods } from './methods/location';
9 | import { JSPteroAPIError } from '../modules/Error';
10 | class Application {
11 | /**
12 | * @param host - Panels address
13 | * @param key - Api key to use
14 | * @param fast - Fast login (No credential check)
15 | */
16 | public constructor(
17 | private host: string,
18 | private key: string,
19 | private errorHandler = (error: JSPteroAPIError): void => {
20 | throw error;
21 | },
22 | fast = false
23 | ) {
24 | host = host.trim();
25 | if (host.endsWith('/')) host = host.slice(0, -1);
26 | this.host = host;
27 | this.request = new Request(this.host, this.key, this.errorHandler).request;
28 | const servermethods = new serverMethods(this);
29 | this.getAllServers = servermethods.getAllServers;
30 | this.getServerInfo = servermethods.getServerInfo;
31 | this.createServer = servermethods.createServer;
32 | this.deleteServer = servermethods.deleteServer;
33 | this.suspendServer = servermethods.suspendServer;
34 | this.unSuspendServer = servermethods.unSuspendServer;
35 | this.reinstallServer = servermethods.reinstallServer;
36 | this.getServerInfoByExtId = servermethods.getServerInfoByExtId;
37 | this.editServerDetails = servermethods.editServerDetails;
38 | this.editServerBuild = servermethods.editServerBuild;
39 | this.editServerStartup = servermethods.editServerStartup;
40 | const nestmethods = new nestMethods(this);
41 | this.getAllNests = nestmethods.getAllNests;
42 | this.getNestInfo = nestmethods.getNestInfo;
43 | this.getAllNestEggs = nestmethods.getAllNestEggs;
44 | this.getEggInfo = nestmethods.getEggInfo;
45 | const databasemethods = new databaseMethods(this);
46 | this.getServersDatabases = databasemethods.getServersDatabases;
47 | this.getServersDatabaseInfo = databasemethods.getServersDatabaseInfo;
48 | this.createDatabase = databasemethods.createDatabase;
49 | this.resetDatabasePassword = databasemethods.resetDatabasePassword;
50 | this.deleteDatabase = databasemethods.deleteDatabase;
51 | const usermethods = new userMethods(this);
52 | this.getAllUsers = usermethods.getAllUsers;
53 | this.getUserInfo = usermethods.getUserInfo;
54 | this.createUser = usermethods.createUser;
55 | this.editUser = usermethods.editUser;
56 | this.deleteUser = usermethods.deleteUser;
57 | const nodemethods = new nodeMethods(this);
58 | this.getAllNodes = nodemethods.getAllNodes;
59 | this.getNodeInfo = nodemethods.getNodeInfo;
60 | this.getNodeConfig = nodemethods.getNodeConfig;
61 | this.createNode = nodemethods.createNode;
62 | this.editNode = nodemethods.editNode;
63 | this.deleteNode = nodemethods.deleteNode;
64 | const allocationmethods = new allocationMethods(this);
65 | this.getAllAllocations = allocationmethods.getAllAllocations;
66 | this.createAllocation = allocationmethods.createAllocation;
67 | this.deleteAllocation = allocationmethods.deleteAllocation;
68 | const locationmethods = new locationMethods(this);
69 | this.getAllLocations = locationmethods.getAllLocations;
70 | this.getLocationInfo = locationmethods.getLocationInfo;
71 | this.createLocation = locationmethods.createLocation;
72 | this.editLocation = locationmethods.editLocation;
73 | this.deleteLocation = locationmethods.deleteLocation;
74 |
75 | if (!fast) this.testAPI();
76 | }
77 | /**
78 | * @param throwError - Whether to throw an error or return bool
79 | * @remarks Will not work if using custom error handler.
80 | */
81 | public testAPI = async (throwError = true): Promise => {
82 | try {
83 | await this.getAllServers();
84 | return true;
85 | } catch (e) {
86 | if (e instanceof JSPteroAPIError) {
87 | if (throwError) {
88 | if (e.HTML_STATUS === 403) e.ERRORS = ['Invalid Application API key'];
89 | throw e;
90 | }
91 | return false;
92 | } else {
93 | if (throwError) throw e;
94 | return false;
95 | }
96 | }
97 | };
98 |
99 | /**
100 | @internal
101 | */
102 | public request;
103 |
104 | // GET
105 | public getAllServers;
106 | public getAllNodes;
107 | public getAllUsers;
108 | public getUserInfo;
109 | public getNodeInfo;
110 | public getServerInfo;
111 | public getAllNests;
112 | public getNestInfo;
113 | public getAllNestEggs;
114 | public getEggInfo;
115 | public getServerInfoByExtId;
116 | public getServersDatabases;
117 | public getServersDatabaseInfo;
118 | public getNodeConfig;
119 | public getAllAllocations;
120 | public getAllLocations;
121 | public getLocationInfo;
122 | // POST
123 | public createUser;
124 | public createServer;
125 | public createNode;
126 | public createDatabase;
127 | public suspendServer;
128 | public unSuspendServer;
129 | public reinstallServer;
130 | public resetDatabasePassword;
131 | public createAllocation;
132 | public createLocation;
133 | // PATCH
134 | public editUser;
135 | public editServerDetails;
136 | public editServerBuild;
137 | public editServerStartup;
138 | public editNode;
139 | public editLocation;
140 | // DELETE
141 | public deleteUser;
142 | public deleteNode;
143 | public deleteServer;
144 | public deleteDatabase;
145 | public deleteAllocation;
146 | public deleteLocation;
147 | }
148 |
149 | export { Application };
150 |
--------------------------------------------------------------------------------
/src/application/interfaces/Allocation.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationAllocation */
2 | import { Node } from './Node';
3 | import { Server } from './Server';
4 |
5 | export interface AllocationIncludeInput {
6 | node?: boolean;
7 | server?: boolean;
8 | }
9 |
10 | export interface AllocationFilterInput {
11 | filter: string;
12 | filterBy: 'ip' | 'port' | 'ip_alias' | 'server_id';
13 | }
14 |
15 | export interface AllocationRelationships {
16 | server?: Server;
17 | node?: Node;
18 | }
19 |
20 | export interface AllocationAttributes {
21 | id: number;
22 | ip: string;
23 | alias: string | null;
24 | port: number;
25 | notes: string | null;
26 | assigned: boolean;
27 | relationships?: AllocationRelationships;
28 | }
29 |
30 | export interface Allocation {
31 | onject: string;
32 | attributes: AllocationAttributes;
33 | }
34 |
35 | export interface Allocations {
36 | object: string;
37 | data: Allocation[];
38 | meta: {
39 | pagination: {
40 | total: number;
41 | count: number;
42 | per_page: number;
43 | current_page: number;
44 | total_pages: number;
45 | };
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/src/application/interfaces/Database.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationDatabase */
2 | export interface DatabaseIncludeInput {
3 | password?: boolean;
4 | host?: boolean;
5 | }
6 |
7 | export interface DatabasePasswordAttributes {
8 | password: string;
9 | }
10 | export interface DatabasePassword {
11 | object: string;
12 | attributes: DatabasePasswordAttributes;
13 | }
14 |
15 | export interface DatabaseHostAttributes {
16 | id: number;
17 | name: string;
18 | host: string;
19 | port: number;
20 | username: string;
21 | node: number;
22 | created_at: string;
23 | updated_at: string;
24 | }
25 |
26 | export interface DatabaseHost {
27 | object: string;
28 | attributes: DatabaseHostAttributes;
29 | }
30 |
31 | export interface DatabaseRelationships {
32 | password?: DatabasePassword;
33 | host?: DatabaseHost;
34 | }
35 | export interface DatabaseAttributes {
36 | id: number;
37 | server: number;
38 | host: number;
39 | database: string;
40 | username: string;
41 | remote: string;
42 | max_connections: null | number;
43 | created_at: string;
44 | updated_at: string;
45 | relationships?: DatabaseRelationships;
46 | }
47 |
48 | export interface Database {
49 | object: string;
50 | attributes: DatabaseAttributes;
51 | }
52 |
--------------------------------------------------------------------------------
/src/application/interfaces/Egg.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationEgg*/
2 | import { Nest } from './Nest';
3 | import { Server } from './Server';
4 |
5 | export interface EggConfig {
6 | files: unknown[];
7 | startup: Record;
8 | stop: string;
9 | logs: unknown[];
10 | file_denylist: string[];
11 | extends: null | unknown;
12 | }
13 |
14 | export interface EggScript {
15 | privileged: boolean;
16 | install: string;
17 | entry: string;
18 | container: string;
19 | extends: null;
20 | }
21 |
22 | export interface EggVariableDataAttributes {
23 | id: number;
24 | egg_id: number;
25 | name: string;
26 | description: string;
27 | env_variable: string;
28 | default_value: string;
29 | user_viewable: boolean;
30 | user_editable: boolean;
31 | rules: string;
32 | created_at: string;
33 | updated_at: string;
34 | }
35 |
36 | export interface EggVariableData {
37 | object: string;
38 | attributes: EggVariableDataAttributes;
39 | }
40 |
41 | export interface EggVariables {
42 | object: string;
43 | data: EggVariableData[];
44 | }
45 |
46 | export interface EggServers {
47 | object: string;
48 | data: Server[];
49 | }
50 |
51 | export interface EggRelationships {
52 | nest?: Nest;
53 | servers?: EggServers;
54 | variables?: EggVariables;
55 | }
56 |
57 | export interface EggAttributes {
58 | id: number;
59 | uuid: string;
60 | name: string;
61 | nest: number;
62 | author: string;
63 | description: string;
64 | docker_image: string;
65 | docker_images: Record;
66 | config: EggConfig;
67 | startup: string;
68 | script: EggScript;
69 | created_at: '2021-01-27T13:46:16+00:00';
70 | updated_at: '2021-01-27T13:46:16+00:00';
71 | relationships?: EggRelationships;
72 | }
73 |
74 | export interface Egg {
75 | object: string;
76 | attributes: EggAttributes;
77 | }
78 |
--------------------------------------------------------------------------------
/src/application/interfaces/Location.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationLocation */
2 |
3 | import { Node } from './Node';
4 | import { Server } from './Server';
5 |
6 | export interface LocationIncludeInput {
7 | nodes?: boolean;
8 | servers?: boolean;
9 | }
10 |
11 | export interface LocationFilterInput {
12 | filter: string;
13 | filterBy: 'short' | 'long';
14 | }
15 |
16 | export interface LocationNodes {
17 | object: string;
18 | data: Node[];
19 | }
20 |
21 | export interface LocationServers {
22 | object: string;
23 | data: Server[];
24 | }
25 |
26 | export interface LocationRelationships {
27 | nodes?: LocationNodes;
28 | servers?: LocationServers;
29 | }
30 |
31 | export interface LocationAttributes {
32 | id: number;
33 | short: string;
34 | long: string;
35 | updated_at: string;
36 | created_at: string;
37 | relationships?: LocationRelationships;
38 | }
39 |
40 | export interface Location {
41 | object: string;
42 | attributes: LocationAttributes;
43 | }
44 |
45 | export interface Locations {
46 | object: string;
47 | data: Location[];
48 | meta: {
49 | pagination: {
50 | total: number;
51 | count: number;
52 | per_page: number;
53 | current_page: number;
54 | total_pages: number;
55 | };
56 | };
57 | }
58 |
59 | export interface EditLocationOptions {
60 | /** The short name */
61 | shortName?: string;
62 | /** The description */
63 | description?: string;
64 | /** Include information about locations relationships */
65 | options?: LocationIncludeInput;
66 | }
67 |
--------------------------------------------------------------------------------
/src/application/interfaces/Nest.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationNest */
2 | import { Egg } from './Egg';
3 | import { Server } from './Server';
4 |
5 | export interface NestIncludeInput {
6 | eggs?: boolean;
7 | servers?: boolean;
8 | }
9 |
10 | export interface EggIncludeInput {
11 | nest?: boolean;
12 | servers?: boolean;
13 | variables?: boolean;
14 | }
15 |
16 | export interface NestServers {
17 | object: string;
18 | data: Server[];
19 | }
20 |
21 | export interface NestEggs {
22 | object: string;
23 | data: Egg[];
24 | }
25 |
26 | export interface NestRelationships {
27 | eggs?: NestEggs;
28 | servers?: NestServers;
29 | }
30 |
31 | export interface NestAttributes {
32 | id: number;
33 | uuid: string;
34 | author: string;
35 | name: string;
36 | description: string | null;
37 | created_at: string;
38 | updated_at: string;
39 | relationships?: NestRelationships;
40 | }
41 |
42 | export interface Nest {
43 | object: string;
44 | attributes: NestAttributes;
45 | }
46 |
47 | export interface Nests {
48 | object: string;
49 | data: Nest[];
50 | meta: {
51 | pagination: {
52 | total: number;
53 | count: number;
54 | per_page: number;
55 | current_page: number;
56 | total_pages: number;
57 | };
58 | };
59 | }
60 |
--------------------------------------------------------------------------------
/src/application/interfaces/Node.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationNode */
2 | import { Allocations } from './Allocation';
3 | import { Location } from './Location';
4 | import { Server } from './Server';
5 |
6 | export interface NodeIncludeInput {
7 | allocations?: boolean;
8 | location?: boolean;
9 | servers?: boolean;
10 | }
11 |
12 | export interface NodeFilterInput {
13 | filter: string;
14 | filterBy: 'uuid' | 'name' | 'fqdn' | 'daemon_token_id';
15 | }
16 |
17 | export interface NodeConfigSsl {
18 | enabled: boolean;
19 | cert: string;
20 | key: string;
21 | }
22 |
23 | export interface NodeConfigApi {
24 | host: string;
25 | port: number;
26 | ssl: NodeConfigSsl;
27 | upload_limit: number;
28 | }
29 |
30 | export interface NodeConfigSftp {
31 | bind_port: number;
32 | }
33 |
34 | export interface NodeConfigSystem {
35 | data: string;
36 | sftp: NodeConfigSftp;
37 | }
38 |
39 | export interface NodeConfig {
40 | debug: boolean;
41 | uuid: string;
42 | token_id: string;
43 | token: string;
44 | api: NodeConfigApi;
45 | system: NodeConfigSystem;
46 | allowed_mounts: string[];
47 | remote: string;
48 | }
49 |
50 | export interface NodeAllocatedResources {
51 | memory: number;
52 | disk: number;
53 | }
54 |
55 | export interface NodeServers {
56 | object: string;
57 | data: Server[];
58 | }
59 |
60 | export interface NodeRelationships {
61 | allocations?: Allocations;
62 | location?: Location;
63 | servers?: NodeServers;
64 | }
65 |
66 | export interface NodeAttributes {
67 | id: number;
68 | uuid: string;
69 | public: boolean;
70 | name: string;
71 | description: null | string;
72 | location_id: number;
73 | fqdn: string;
74 | scheme: string;
75 | behind_proxy: boolean;
76 | maintenance_mode: boolean;
77 | memory: number;
78 | memory_overallocate: number;
79 | disk: number;
80 | disk_overallocate: number;
81 | upload_size: number;
82 | daemon_listen: number;
83 | daemon_sftp: number;
84 | daemon_base: string;
85 | created_at: string;
86 | updated_at: string;
87 | allocated_resources: NodeAllocatedResources;
88 | relationships?: NodeRelationships;
89 | }
90 |
91 | export interface Node {
92 | object: string;
93 | attributes: NodeAttributes;
94 | }
95 |
96 | export interface Nodes {
97 | object: string;
98 | data: Node[];
99 | meta: {
100 | pagination: {
101 | total: number;
102 | count: number;
103 | per_page: number;
104 | current_page: number;
105 | total_pages: number;
106 | };
107 | };
108 | }
109 |
110 | export interface NodeEditOptions {
111 | name?: string;
112 | description?: string;
113 | locationID?: number;
114 | fqdn?: string;
115 | scheme?: 'http' | 'https';
116 | ram?: number;
117 | disk?: number;
118 | isPublic?: boolean;
119 | daemonPort?: number;
120 | daemonSFTPPort?: number;
121 | ramOverAllocate?: number;
122 | diskOverallocate?: number;
123 | daemonDir?: string;
124 | maintenceMode?: boolean;
125 | maxUploadSize?: number;
126 | behindProxy?: boolean;
127 | resetSecret: boolean;
128 | options?: NodeIncludeInput;
129 | }
130 |
--------------------------------------------------------------------------------
/src/application/interfaces/Server.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationServer */
2 | import { Database } from './Database';
3 | import { Egg } from './Egg';
4 | import { Location } from './Location';
5 | import { Nest } from './Nest';
6 | import { Node } from './Node';
7 | import { User } from './User';
8 |
9 | export interface ServerEnvironment {
10 | [key: string]: string | undefined;
11 | MAX_USERS?: string;
12 | MUMBLE_VERSION?: string;
13 | TS_VERSION?: string;
14 | FILE_TRANSFER?: string;
15 | ARK_PASSWORD?: string;
16 | ARK_ADMIN_PASSWORD?: string;
17 | SERVER_MAP?: string;
18 | SRCDS_APPID?: string;
19 | SESSION_NAME?: string;
20 | ENABLE_RCON?: string;
21 | RCON_PORT?: string;
22 | QUERY_PORT?: string;
23 | AUTO_UPDATE?: string;
24 | BATTLE_EYE?: string;
25 | SRCDS_MAP?: string;
26 | STEAM_ACC?: string;
27 | SRCDS_GAME?: string;
28 | WORKSHOP_ID?: string;
29 | GAMEMODE?: string;
30 | MAX_PLAYERS?: string;
31 | TICKRATE?: string;
32 | INSTALL_REPO?: string;
33 | USERNAME?: string;
34 | PASSWORD?: string;
35 | INSTALL_BRANCH?: string;
36 | USER_UPLOAD?: string;
37 | BOT_JS_FILE?: string;
38 | NODE_PACKAGES?: string;
39 | BUNGEE_VERSION?: string;
40 | SERVER_JARFILE?: string;
41 | MC_VERSION?: string;
42 | BUILD_TYPE?: string;
43 | FORGE_VERSION?: string;
44 | MINECRAFT_VERSION?: string;
45 | DL_PATH?: string;
46 | BUILD_NUMBER?: string;
47 | SPONGE_VERSION?: string;
48 | VANILLA_VERSION?: string;
49 | HOSTNAME?: string;
50 | OXIDE?: string;
51 | LEVEL?: string;
52 | DESCRIPTION?: string;
53 | SERVER_URL?: string;
54 | WORLD_SIZE?: string;
55 | WORLD_SEED?: string;
56 | SERVER_IMG?: string;
57 | RCON_PASS?: string;
58 | SAVEINTERVAL?: string;
59 | ADDITIONAL_ARGS?: string;
60 | }
61 |
62 | export interface ServerFilterInput {
63 | filter: string;
64 | filterBy: 'uuidShort' | 'uuid' | 'name' | 'external_id' | 'image';
65 | }
66 |
67 | export interface ServerIncludesInput {
68 | allocations?: boolean;
69 | user?: boolean;
70 | subusers?: boolean;
71 | nest?: boolean;
72 | egg?: boolean;
73 | variables?: boolean;
74 | location?: boolean;
75 | node?: boolean;
76 | databases?: boolean;
77 | }
78 |
79 | export interface ServerLimits {
80 | memory: number;
81 | swap: number;
82 | disk: number;
83 | io: number;
84 | cpu: number;
85 | threads: null | string | number;
86 | }
87 |
88 | export interface ServerFeatureLimits {
89 | databases: number;
90 | allocations: number;
91 | backups: number;
92 | }
93 |
94 | export interface ServerContainer {
95 | startup_command: string;
96 | image: string;
97 | installed: boolean;
98 | environment: ServerEnvironment;
99 | }
100 |
101 | export interface ServerAllocations {
102 | object: string;
103 | data: ServerAllocation[];
104 | }
105 |
106 | export interface ServerAllocation {
107 | object: string;
108 | attributes: ServerAllocationAttributes;
109 | }
110 |
111 | export interface ServerAllocationAttributes {
112 | id: number;
113 | ip: string;
114 | alias: string;
115 | port: number;
116 | notes: null | string;
117 | assigned: boolean;
118 | }
119 |
120 | export interface ServerVariables {
121 | object: string;
122 | data: ServerVariable[];
123 | }
124 |
125 | export interface ServerVariable {
126 | object: string;
127 | attributes: ServerVariableAttributes;
128 | }
129 |
130 | export interface ServerVariableAttributes {
131 | id: number;
132 | egg_id: number;
133 | name: string;
134 | description: string;
135 | env_variable: string;
136 | default_value: string;
137 | user_viewable: boolean;
138 | user_editable: boolean;
139 | rules: string;
140 | created_at: string;
141 | updated_at: string;
142 | server_value: string;
143 | }
144 |
145 | export interface ServerSubUsers {
146 | object: string;
147 | data: ServerSubUser[];
148 | }
149 |
150 | export interface ServerSubUser {
151 | object: 'subuser';
152 | attributes: ServerSubUserAttributes;
153 | }
154 |
155 | export interface ServerSubUserAttributes {
156 | id: number;
157 | user_id: number;
158 | server_id: number;
159 | permissions: string[];
160 | created_at: string;
161 | updated_at: string;
162 | }
163 |
164 | export interface ServerDatabases {
165 | object: string;
166 | data: Database[];
167 | }
168 |
169 | export interface ServerRelationships {
170 | allocations?: ServerAllocations;
171 | user?: User;
172 | subusers?: ServerSubUsers;
173 | nest?: Nest;
174 | egg?: Egg;
175 | variables?: ServerVariables;
176 | location?: Location;
177 | node?: Node;
178 | databases?: ServerDatabases;
179 | }
180 |
181 | export interface ServerAttributes {
182 | id: number;
183 | external_id: null;
184 | uuid: string;
185 | identifier: string;
186 | name: string;
187 | description: string;
188 | suspended: boolean;
189 | limits: ServerLimits;
190 | feature_limits: ServerFeatureLimits;
191 | user: number;
192 | node: number;
193 | allocation: number;
194 | nest: number;
195 | egg: number;
196 | container: ServerContainer;
197 | updated_at: string;
198 | created_at: string;
199 | relationships?: ServerRelationships;
200 | }
201 |
202 | export interface Server {
203 | object: string;
204 | attributes: ServerAttributes;
205 | }
206 |
207 | export interface Servers {
208 | object: string;
209 | data: Server[];
210 | meta: {
211 | pagination: {
212 | total: number;
213 | count: number;
214 | per_page: number;
215 | current_page: number;
216 | total_pages: number;
217 | };
218 | };
219 | }
220 |
221 | export interface EditServerDetails {
222 | /** New server name */
223 | name?: string;
224 | /** ID of the new server owner */
225 | userId?: number;
226 | /** Set the new external ID */
227 | externalId?: string;
228 | /** Set new description */
229 | description?: string;
230 | /** Include information about server relationships */
231 | options?: ServerIncludesInput;
232 | }
233 |
234 | export interface EditServerBuild {
235 | /** The new primary allocation id */
236 | allocationId?: number;
237 | /** Array of new allocation ids to add */
238 | addAllocations?: number[];
239 | /** Array of allocation ids to remove from server */
240 | removeAllocations?: number[];
241 | /** Amount of cpu resources to give (1 core = 100) (0 unlimited) */
242 | cpu?: number;
243 | /** Amount of memory resources to give (1024 = 1GB) (0 unlimited) */
244 | memory?: number;
245 | /** Amount of disk space to give (1024 = 1GB) (0 unlimited) */
246 | disk?: number;
247 | /** Amount databases server can create */
248 | databases?: number;
249 | /** Amount allocations server can create */
250 | allocations?: number;
251 | /** Amount backups server can create */
252 | backups?: number;
253 | /** Amount swap resources to give (1024 = 1GB) (-1 unlimited) */
254 | swap?: number;
255 | /** ADVANCED IO performance of the host server (between 10 and 1000) */
256 | io?: number;
257 | /** ADVANCED Threads for the server to use */
258 | threads?: string;
259 | /** Include information about server relationships */
260 | options?: ServerIncludesInput;
261 | }
262 |
263 | export interface EditServerStartup {
264 | startup?: string;
265 | environment?: ServerEnvironment;
266 | egg?: number;
267 | image?: string;
268 | options?: ServerIncludesInput;
269 | skip_scripts?: boolean;
270 | }
271 |
--------------------------------------------------------------------------------
/src/application/interfaces/User.ts:
--------------------------------------------------------------------------------
1 | /** @module ApplicationUser */
2 | import { Server } from './Server';
3 |
4 | export interface UserIncludeInput {
5 | servers: boolean;
6 | }
7 |
8 | export interface UserFilterInput {
9 | filter: string;
10 | filterBy: 'email' | 'uuid' | 'username' | 'external_id';
11 | }
12 |
13 | export interface UserServers {
14 | object: string;
15 | data: Server[];
16 | }
17 |
18 | export interface UserRelationships {
19 | servers: UserServers;
20 | }
21 |
22 | export interface UserAttributes {
23 | 'id': number;
24 | 'external_id': string | null;
25 | 'uuid': string;
26 | 'username': string;
27 | 'email': string;
28 | 'first_name': string;
29 | 'last_name': string;
30 | 'language': string;
31 | 'root_admin': boolean;
32 | '2fa': boolean;
33 | 'created_at': string;
34 | 'updated_at': string;
35 | 'relationships'?: UserRelationships;
36 | }
37 |
38 | export interface User {
39 | object: string;
40 | attributes: UserAttributes;
41 | }
42 |
43 | export interface Users {
44 | object: string;
45 | data: User[];
46 | meta: {
47 | pagination: {
48 | total: number;
49 | count: number;
50 | per_page: number;
51 | current_page: number;
52 | total_pages: number;
53 | };
54 | };
55 | }
56 |
57 | export interface EditUserOptions {
58 | /** The new username of the user */
59 | username?: string;
60 | /** The new first name of the user */
61 | firstName?: string;
62 | /** The new last name of the user */
63 | lastName?: string;
64 | /** The new email address of the user */
65 | email?: string;
66 | /** The new password of the user */
67 | password?: string;
68 | /** Is the user admin */
69 | isAdmin?: boolean;
70 | /** The new language of the user */
71 | language?: string;
72 | /** The new external id of user */
73 | externalId?: string;
74 | /** Include information about relationships */
75 | options?: UserIncludeInput;
76 | }
77 |
--------------------------------------------------------------------------------
/src/application/methods/allocation.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
2 | import {
3 | Allocation,
4 | AllocationFilterInput,
5 | AllocationIncludeInput,
6 | Allocations
7 | } from '../interfaces/Allocation';
8 | import { Application } from '../index';
9 |
10 | export class allocationMethods {
11 | constructor(private readonly application: Application) {}
12 | /**
13 | * @internal
14 | */
15 | private getAllocations = async (
16 | nodeId: number,
17 | options: MakeOpts
18 | ): Promise => {
19 | return this.application.request(
20 | 'GET',
21 | null,
22 | '',
23 | `/api/application/nodes/${nodeId}/allocations${makeOptions(options)}`
24 | );
25 | };
26 | /**
27 | * @param nodeId - The node id of which you want to get allocations from
28 | * @param options - Include information about relationships
29 | * @returns Returns information about node
30 | * @example
31 | * ```ts
32 | * const res = await app.getAllAllocations(1) // res = NodeAttributes
33 | * ```
34 | * @example
35 | * ```ts
36 | * app.getAllAllocations(1).then((res) => console.log(res)) // res = NodeAttributes
37 | * ```
38 | */
39 | public getAllAllocations = async (
40 | nodeId: number,
41 | options?: AllocationIncludeInput,
42 | filter?: AllocationFilterInput
43 | ): Promise => {
44 | return await paginate(this.getAllocations.bind(this, nodeId), {
45 | includes: { ...options },
46 | filter
47 | });
48 | };
49 | /**
50 | * @param nodeId - The node id of which you want to create allocations
51 | * @param ports - Ports array to add
52 | * @param alias - The alias for this allocation
53 | * @param ip - IP for the allocation
54 | * @returns If successful returns Successfully created!
55 | * @example
56 | * ```ts
57 | * const res = await app.createAllocation(1, ['25565']) // res = Successfully created!
58 | * ```
59 | * @example
60 | * ```ts
61 | * app.createAllocation(1, ['25565'], 'minecraft').then((res) => console.log(res)) // res = Successfully created!
62 | * ```
63 | */
64 | public createAllocation = async (
65 | nodeId: number,
66 | ports: string[],
67 | alias = '',
68 | ip = '0.0.0.0'
69 | ): Promise => {
70 | return this.application.request(
71 | 'POST',
72 | {
73 | ip: ip,
74 | ports: ports,
75 | allocation_alias: alias
76 | },
77 | 'Successfully created!',
78 | `/api/application/nodes/${nodeId}/allocations`
79 | );
80 | };
81 | /**
82 | * @param nodeId - The node id of which you want to delete allocation
83 | * @param allocationId - The id of allocation to delete
84 | * @returns If successful returns Successfully deleted!
85 | * @example
86 | * ```ts
87 | * const res = await app.deleteAllocation(1, 5) // res = Successfully deleted!
88 | * ```
89 | * @example
90 | * ```ts
91 | * app.deleteAllocation(1, 8).then((res) => console.log(res)) // res = Successfully deleted!
92 | * ```
93 | */
94 | public deleteAllocation = async (
95 | nodeId: number,
96 | allocationId: number
97 | ): Promise => {
98 | return this.application.request(
99 | 'DELETE',
100 | null,
101 | 'Successfully deleted!',
102 | `/api/application/nodes/${nodeId}/allocations/${allocationId}`
103 | );
104 | };
105 | }
106 |
--------------------------------------------------------------------------------
/src/application/methods/database.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions } from '../../modules/Functions';
2 | import {
3 | Database,
4 | DatabaseAttributes,
5 | DatabaseIncludeInput
6 | } from '../interfaces/Database';
7 | import { Application } from '../index';
8 |
9 | export class databaseMethods {
10 | constructor(private readonly application: Application) {}
11 | /**
12 | * @param serverId - The server ID to get the databases from
13 | * @param options - Include information about server relationships
14 | * @returns Array of databases
15 | * @example
16 | * ```ts
17 | * const res = await app.getServersDatabase(1) // res = Database[]
18 | * ```
19 | * @example
20 | * ```ts
21 | * app.getServersDatabase(1).then((res) => console.log(res)) // res = Database[]
22 | * ```
23 | */
24 | public getServersDatabases = async (
25 | serverId: number,
26 | options?: DatabaseIncludeInput
27 | ): Promise => {
28 | return this.application.request(
29 | 'GET',
30 | null,
31 | 'data',
32 | `/api/application/servers/${serverId}/databases${makeOptions({
33 | includes: { ...options }
34 | })}`
35 | );
36 | };
37 | /**
38 | * @param serverId - The server ID to get the database from
39 | * @param databaseId - The ID of the database
40 | * @param options - Include information about server relationships
41 | * @returns Database information
42 | * @example
43 | * ```ts
44 | * const res = await app.getServersDatabaseInfo(1, 1) // res = DatabaseAttributes
45 | * ```
46 | * @example
47 | * ```ts
48 | * app.getServersDatabaseInfo(1, 2).then((res) => console.log(res)) // res = DatabaseAttributes
49 | * ```
50 | */
51 | public getServersDatabaseInfo = async (
52 | serverId: number,
53 | databaseId: number,
54 | options?: DatabaseIncludeInput
55 | ): Promise => {
56 | return this.application.request(
57 | 'GET',
58 | null,
59 | 'attributes',
60 | `/api/application/servers/${serverId}/databases/${databaseId}${makeOptions(
61 | { includes: { ...options } }
62 | )}`
63 | );
64 | };
65 | /**
66 | * @param name - Name of the Database
67 | * @param dbHostId - ID of the Database Host
68 | * @param serverId - The server ID to create the database in
69 | * @param allowedIp - IP allowed to connect, leave "%" if you dont want to restrict
70 | * @param options - Include information about server relationships
71 | * @returns Information about the new database
72 | * @example
73 | * ```ts
74 | * const res = await app.createDatabase('DATABASE_1', 1, 1) // res = DatabaseAttributes
75 | * ```
76 | * @example
77 | * ```ts
78 | * app.createDatabase('DATABASE_1', 1, 1).then((res) => console.log(res)) // res = DatabaseAttributes
79 | * ```
80 | */
81 | public createDatabase = async (
82 | name: string,
83 | dbHostId: number,
84 | serverId: number,
85 | allowedIp = '%',
86 | options?: DatabaseIncludeInput
87 | ): Promise => {
88 | return this.application.request(
89 | 'POST',
90 | {
91 | database: name,
92 | remote: allowedIp,
93 | host: dbHostId
94 | },
95 | 'attributes',
96 | `/api/application/servers/${serverId}/databases${makeOptions({
97 | includes: { ...options }
98 | })}`
99 | );
100 | };
101 | /**
102 | * @param serverId - The server ID to get the database from
103 | * @param databaseId - The ID of the database
104 | * @returns If successful returns Successfully reset the password!
105 | * @example
106 | * ```ts
107 | * const res = await app.resetDatabasePassword(1, 1) // res = Successfully reset the password!
108 | * ```
109 | * @example
110 | * ```ts
111 | * app.resetDatabasePassword(1, 2).then((res) => console.log(res)) // res = Successfully reset the password!
112 | * ```
113 | */
114 | public resetDatabasePassword = async (
115 | serverId: number,
116 | databaseId: number
117 | ): Promise => {
118 | return this.application.request(
119 | 'POST',
120 | null,
121 | 'Successfully reset the password!',
122 | `/api/application/servers/${serverId}/databases/${databaseId}/reset-password`
123 | );
124 | };
125 | /**
126 | * @param serverId - The server ID to delete the database in
127 | * @param databaseId - The ID of the database
128 | * @returns If successful returns Successfully deleted the database!
129 | * @example
130 | * ```ts
131 | * const res = await app.resetDatabasePassword(1, 1) // res = Successfully deleted the database!
132 | * ```
133 | * @example
134 | * ```ts
135 | * app.resetDatabasePassword(1, 2).then((res) => console.log(res)) // res = Successfully deleted the database!
136 | * ```
137 | */
138 | public deleteDatabase = async (
139 | serverId: number,
140 | databaseId: number
141 | ): Promise => {
142 | return this.application.request(
143 | 'DELETE',
144 | null,
145 | 'Successfully deleted the database!',
146 | `/api/application/servers/${serverId}/databases/${databaseId}`
147 | );
148 | };
149 | }
150 |
--------------------------------------------------------------------------------
/src/application/methods/location.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
2 | import {
3 | EditLocationOptions,
4 | Location,
5 | LocationAttributes,
6 | LocationFilterInput,
7 | LocationIncludeInput,
8 | Locations
9 | } from '../interfaces/Location';
10 | import { Application } from '../index';
11 |
12 | export class locationMethods {
13 | constructor(private readonly application: Application) {}
14 | /**
15 | * @internal
16 | */
17 | private getLocations = async (options: MakeOpts): Promise => {
18 | return this.application.request(
19 | 'GET',
20 | null,
21 | '',
22 | `/api/application/locations${makeOptions(options)}`
23 | );
24 | };
25 | /**
26 | * @param options - Include information about locations relationships
27 | * @param filter - Filter Location by specific fields and values
28 | * @returns Array of locations
29 | * @example
30 | * ```ts
31 | * const res = await app.getAllLocations() // res = Location[]
32 | * ```
33 | * @example
34 | * ```ts
35 | * app.getAllLocations().then((res) => console.log(res)) // res = Location[]
36 | * ```
37 | */
38 | public getAllLocations = async (
39 | options?: LocationIncludeInput,
40 | filter?: LocationFilterInput
41 | ): Promise => {
42 | return await paginate(this.getLocations.bind(this), {
43 | includes: { ...options },
44 | filter
45 | });
46 | };
47 | /**
48 | * @param locationId - The location id to get information about
49 | * @param options - Include information about locations relationships
50 | * @returns Location information
51 | * @example
52 | * ```ts
53 | * const res = await app.getLocationInfo(1) // res = LocationAttributes
54 | * ```
55 | * @example
56 | * ```ts
57 | * app.getLocationInfo(1).then((res) => console.log(res)) // res = LocationAttributes
58 | * ```
59 | */
60 | public getLocationInfo = async (
61 | locationId: number,
62 | options?: LocationIncludeInput
63 | ): Promise => {
64 | return this.application.request(
65 | 'GET',
66 | null,
67 | 'attributes',
68 | `/api/application/locations/${locationId}${makeOptions({
69 | includes: { ...options }
70 | })}`
71 | );
72 | };
73 | /**
74 | * @param shortName - The short name of the new location
75 | * @param description - The description of location
76 | * @param options - Include information about locations relationships
77 | * @returns Location information
78 | * @example
79 | * ```ts
80 | * const res = await app.createLocation('Home') // res = LocationAttributes
81 | * ```
82 | * @example
83 | * ```ts
84 | * app.createLocation('Home').then((res) => console.log(res)) // res = LocationAttributes
85 | * ```
86 | */
87 | public createLocation = async (
88 | shortName: string,
89 | description?: string,
90 | options?: LocationIncludeInput
91 | ): Promise => {
92 | return this.application.request(
93 | 'POST',
94 | {
95 | short: shortName,
96 | long: description ? description : ''
97 | },
98 | 'attributes',
99 | `/api/application/locations${makeOptions({
100 | includes: { ...options }
101 | })}`
102 | );
103 | };
104 | /**
105 | * @param locationId - The location id to edit
106 | * @param options - Location edit options
107 | * @returns Location information
108 | * @example
109 | * ```ts
110 | * const res = await app.editLocation(1, 'Homie') // res = LocationAttributes
111 | * ```
112 | * @example
113 | * ```ts
114 | * app.editLocation(1, undefined, 'Very good locaiton').then((res) => console.log(res)) // res = LocationAttributes
115 | * ```
116 | */
117 | public editLocation = async (
118 | locationId: number,
119 | options: EditLocationOptions
120 | ): Promise => {
121 | const location = await this.getLocationInfo(locationId);
122 | return this.application.request(
123 | 'PATCH',
124 | {
125 | short: options.shortName ?? location.short,
126 | long: options.description ?? location.long
127 | },
128 | 'attributes',
129 | `/api/application/locations/${locationId}${makeOptions({
130 | includes: { ...options.options }
131 | })}`
132 | );
133 | };
134 | /**
135 | * @param locationId - The location id to delete
136 | * @returns Successfully deleted the location!
137 | * @example
138 | * ```ts
139 | * const res = await app.deleteLocation(1) // res = Successfully deleted the location!
140 | * ```
141 | * @example
142 | * ```ts
143 | * app.deleteLocation(1).then((res) => console.log(res)) // res = Successfully deleted the location!
144 | * ```
145 | */
146 | public deleteLocation = async (locationId: number): Promise => {
147 | return this.application.request(
148 | 'DELETE',
149 | null,
150 | 'Successfully deleted the location!',
151 | `/api/application/locations/${locationId}`
152 | );
153 | };
154 | }
155 |
--------------------------------------------------------------------------------
/src/application/methods/nest.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
2 | import { Egg, EggAttributes } from '../interfaces/Egg';
3 | import {
4 | Nest,
5 | EggIncludeInput,
6 | NestAttributes,
7 | NestIncludeInput,
8 | Nests
9 | } from '../interfaces/Nest';
10 | import { Application } from '../index';
11 |
12 | export class nestMethods {
13 | constructor(private readonly application: Application) {}
14 | /**
15 | * @internal
16 | */
17 | private getNests = async (options: MakeOpts): Promise => {
18 | return this.application.request(
19 | 'GET',
20 | null,
21 | '',
22 | `/api/application/nests${makeOptions(options)}`
23 | );
24 | };
25 | /**
26 | * @param options - Include information about: eggs or servers
27 | * @returns Array of nests
28 | * @example
29 | * ```ts
30 | * const res = await app.getAllNests() // res = Nest[]
31 | * ```
32 | * @example
33 | * ```ts
34 | * app.getAllNests().then((res) => console.log(res)) // res = Nest[]
35 | * ```
36 | */
37 | public getAllNests = async (options?: NestIncludeInput): Promise => {
38 | return await paginate(this.getNests.bind(this), {
39 | includes: { ...options }
40 | });
41 | };
42 | /**
43 | * @param nestId - The nest ID to get the details of.
44 | * @param options - Include information about: eggs or servers
45 | * @returns Nest details
46 | * @example
47 | * ```ts
48 | * const res = await app.getNestInfo(1) // res = NestAttributes
49 | * ```
50 | * @example
51 | * ```ts
52 | * app.getNestInfo(1).then((res) => console.log(res)) // res = NestAttributes
53 | * ```
54 | */
55 | public getNestInfo = async (
56 | nestId: number,
57 | options?: NestIncludeInput
58 | ): Promise => {
59 | return this.application.request(
60 | 'GET',
61 | null,
62 | 'attributes',
63 | `/api/application/nests/${nestId}${makeOptions({
64 | includes: { ...options }
65 | })}`
66 | );
67 | };
68 | /**
69 | * @param nestId - The nest ID to get the details of.
70 | * @param options - Include information about: nest or servers or variables
71 | * @returns
72 | * @example
73 | * ```ts
74 | * const res = await app.getAllNestEggs(1) // res = Egg[]
75 | * ```
76 | * @example
77 | * ```ts
78 | * app.getAllNestEggs(1).then((res) => console.log(res)) // res = Egg[]
79 | * ```
80 | */
81 | public getAllNestEggs = async (
82 | nestId: number,
83 | options?: EggIncludeInput
84 | ): Promise => {
85 | return this.application.request(
86 | 'GET',
87 | null,
88 | 'data',
89 | `/api/application/nests/${nestId}/eggs${makeOptions({
90 | includes: { ...options }
91 | })}`
92 | );
93 | };
94 | /**
95 | * @param nestId - The nest ID to get the details of.
96 | * @param eggId - Egg ID to use when installing the server
97 | * @param options - Include information about: nest or servers or variables
98 | * @returns
99 | * @example
100 | * ```ts
101 | * const res = await app.getEggInfo(1, 1) // res = EggAttributes
102 | * ```
103 | * @example
104 | * ```ts
105 | * app.getEggInfo(1, 1).then((res) => console.log(res)) // res = EggAttributes
106 | * ```
107 | */
108 | public getEggInfo = async (
109 | nestID: number,
110 | eggId: number,
111 | options?: EggIncludeInput
112 | ): Promise => {
113 | return this.application.request(
114 | 'GET',
115 | null,
116 | 'attributes',
117 | `/api/application/nests/${nestID}/eggs/${eggId}${makeOptions({
118 | includes: { ...options }
119 | })}`
120 | );
121 | };
122 | }
123 |
--------------------------------------------------------------------------------
/src/application/methods/node.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
2 | import {
3 | Node,
4 | NodeAttributes,
5 | NodeConfig,
6 | NodeEditOptions,
7 | NodeFilterInput,
8 | NodeIncludeInput,
9 | Nodes
10 | } from '../interfaces/Node';
11 | import { Application } from '../index';
12 |
13 | export class nodeMethods {
14 | constructor(private readonly application: Application) {}
15 | /**
16 | * @internal
17 | */
18 | private getNodes = async (options: MakeOpts): Promise => {
19 | return this.application.request(
20 | 'GET',
21 | null,
22 | '',
23 | `/api/application/nodes${makeOptions(options)}`
24 | );
25 | };
26 | /**
27 | * @param options - Include information about relationships
28 | * @param filter - Filter Nodes by specific fields and values
29 | * @returns Array of nodes
30 | * @example
31 | * ```ts
32 | * const res = await app.getAllNodes() // res = Node[]
33 | * ```
34 | * @example
35 | * ```ts
36 | * app.getAllNodes().then((res) => console.log(res)) // res = Node[]
37 | * ```
38 | */
39 | public getAllNodes = async (
40 | options?: NodeIncludeInput,
41 | filter?: NodeFilterInput
42 | ): Promise => {
43 | return await paginate(this.getNodes.bind(this), {
44 | includes: { ...options },
45 | filter: filter
46 | });
47 | };
48 | /**
49 | * @param nodeId - The node id of which you want to get information
50 | * @param options - Include information about relationships
51 | * @returns Returns information about node
52 | * @example
53 | * ```ts
54 | * const res = await app.getNodeInfo(1) // res = NodeAttributes
55 | * ```
56 | * @example
57 | * ```ts
58 | * app.getNodeInfo(1).then((res) => console.log(res)) // res = NodeAttributes
59 | * ```
60 | */
61 | public getNodeInfo = async (
62 | nodeId: number,
63 | options?: NodeIncludeInput
64 | ): Promise => {
65 | return this.application.request(
66 | 'GET',
67 | null,
68 | 'attributes',
69 | `/api/application/nodes/${nodeId}${makeOptions({
70 | includes: { ...options }
71 | })}`
72 | );
73 | };
74 | /**
75 | * @param nodeId - The node id of which you want to get information
76 | * @returns Returns information about node config
77 | * @example
78 | * ```ts
79 | * const res = await app.getNodeConfig(1) // res = NodeConfig
80 | * ```
81 | * @example
82 | * ```ts
83 | * app.getNodeConfig(1).then((res) => console.log(res)) // res = NodeConfig
84 | * ```
85 | */
86 | public getNodeConfig = (nodeId: number): Promise => {
87 | return this.application.request(
88 | 'GET',
89 | null,
90 | '',
91 | `/api/application/nodes/${nodeId}/configuration`
92 | );
93 | };
94 | /**
95 | * @param name - The name of the node
96 | * @param description - A description for the node
97 | * @param locationId - Location ID to use
98 | * @param fqdn - Fully Qualified Domain Name (If you're using an IP scheme needs to be http)
99 | * @param scheme - Scheme to use: http or https
100 | * @param ram - How much RAM should be allocated for the node?
101 | * @param disk - How much disk space be allocated for the node?
102 | * @param isPublic - Is this node public?
103 | * @param daemonPort - The daemon port (default 8080)
104 | * @param daemonSFTPPort - The daemon sftp port (default 2022)
105 | * @param ramOverAllocate - Ram overallocation (default -1)
106 | * @param diskOverallocate - Disk overallocation (default -1)
107 | * @param daemonDir - Directory of the daemon, normally /var/lib/pterodactyl/volumes
108 | * @param maintenceMode - Is the node in maintence mode?
109 | * @param maxUploadSize - Upload size (1-1024)
110 | * @param behindProxy - Is the node behind a proxy?
111 | * @param options - Include information about relationships
112 | * @returns Information about the new node
113 | * @example
114 | * ```ts
115 | * const res = await app.createNode('NEW node', 'Good node', 1, 'node.gfd.com', 'https', 8192, 500000) // res = NodeAttributes
116 | * ```
117 | * @example
118 | * ```ts
119 | * app.createNode('NEW node', 'Good node', 1, 'node.gfd.com', 'https', 8192, 500000).then((res) => console.log(res)) // res = NodeAttributes
120 | * ```
121 | */
122 | public createNode = async (
123 | name: string,
124 | description: string,
125 | locationID: number,
126 | fqdn: string,
127 | scheme: 'http' | 'https',
128 | ram: number,
129 | disk: number,
130 | isPublic = true,
131 | daemonPort = 8080,
132 | daemonSFTPPort = 2022,
133 | ramOverAllocate = -1,
134 | diskOverallocate = -1,
135 | daemonDir = '/var/lib/pterodactyl/volumes',
136 | maintenceMode = false,
137 | maxUploadSize = 100,
138 | behindProxy = false,
139 | options?: NodeIncludeInput
140 | ): Promise => {
141 | return this.application.request(
142 | 'POST',
143 | {
144 | name: name,
145 | description: description,
146 | location_id: locationID,
147 | public: isPublic,
148 | fqdn: fqdn,
149 | scheme: scheme,
150 | behind_proxy: behindProxy,
151 | memory: ram,
152 | memory_overallocate: ramOverAllocate,
153 | disk: disk,
154 | disk_overallocate: diskOverallocate,
155 | daemon_base: daemonDir,
156 | daemon_listen: daemonPort,
157 | daemon_sftp: daemonSFTPPort,
158 | maintenance_mode: maintenceMode,
159 | upload_size: maxUploadSize
160 | },
161 | 'attributes',
162 | `/api/application/nodes${makeOptions({
163 | includes: { ...options }
164 | })}`
165 | );
166 | };
167 | /**
168 | * @param nodeId - The node id of which you want to get information
169 | * @param name - The name of the node
170 | * @param description - A description for the node
171 | * @param locationId - Location ID to use
172 | * @param fqdn - Fully Qualified Domain Name (If you're using an IP scheme needs to be http)
173 | * @param scheme - Scheme to use: http or https
174 | * @param ram - How much RAM should be allocated for the node?
175 | * @param disk - How much disk space be allocated for the node?
176 | * @param isPublic - Is this node public?
177 | * @param daemonPort - The daemon port (default 8080)
178 | * @param daemonSFTPPort - The daemon sftp port (default 2022)
179 | * @param ramOverAllocate - Ram overallocation (default -1)
180 | * @param diskOverallocate - Disk overallocation (default -1)
181 | * @param daemonDir - Directory of the daemon, normally /var/lib/pterodactyl/volumes
182 | * @param maintenceMode - Is the node in maintence mode?
183 | * @param maxUploadSize - Upload size (1-1024)
184 | * @param behindProxy - Is the node behind a proxy?
185 | * @param resetSecret - Reset daemonds token?
186 | * @param options - Include information about relationships
187 | * @returns Information about the new node
188 | * @example
189 | * ```ts
190 | * const res = await app.editNode('NEW node', 'Good node', 1, 'node.gfd.com', 'https', 8192, 500000) // res = NodeAttributes
191 | * ```
192 | * @example
193 | * ```ts
194 | * app.editNode('NEW node', undefined, 1, 'node.gfd.com', undefined, 8192, 500000).then((res) => console.log(res)) // res = NodeAttributes
195 | * ```
196 | */
197 | public editNode = async (
198 | nodeId: number,
199 | options: NodeEditOptions
200 | ): Promise => {
201 | const node = await this.getNodeInfo(nodeId);
202 | return this.application.request(
203 | 'PATCH',
204 | {
205 | name: options.name ?? node.name,
206 | description: options.description ?? node.description,
207 | location_id: options.locationID ?? node.location_id,
208 | public: options.isPublic ?? node.public,
209 | fqdn: options.fqdn ?? node.fqdn,
210 | scheme: options.scheme ?? node.scheme,
211 | behind_proxy: options.behindProxy ?? node.behind_proxy,
212 | memory: options.ram ?? node.memory,
213 | memory_overallocate:
214 | options.ramOverAllocate ?? node.memory_overallocate,
215 | disk: options.disk ?? node.disk,
216 | disk_overallocate: options.diskOverallocate ?? node.disk_overallocate,
217 | daemon_base: options.daemonDir ?? node.daemon_base,
218 | daemon_listen: options.daemonPort ?? node.daemon_listen,
219 | daemon_sftp: options.daemonSFTPPort ?? node.daemon_sftp,
220 | maintenance_mode: options.maintenceMode ?? node.maintenance_mode,
221 | upload_size: options.maxUploadSize ?? node.upload_size,
222 | reset_secret: options.resetSecret
223 | },
224 | 'attributes',
225 | `/api/application/nodes/${nodeId}${makeOptions({
226 | includes: { ...options.options }
227 | })}`
228 | );
229 | };
230 | /**
231 | * @param nodeId - The node id of which you want to get information
232 | * @returns If successful returns Successfully deleted!
233 | * @example
234 | * ```ts
235 | * const res = await app.deleteNode(1) // res = Successfully deleted!
236 | * ```
237 | * @example
238 | * ```ts
239 | * app.deleteNode(1).then((res) => console.log(res)) // res = Successfully deleted!
240 | * ```
241 | */
242 | public deleteNode = async (nodeId: number): Promise => {
243 | return this.application.request(
244 | 'DELETE',
245 | null,
246 | 'Successfully deleted!',
247 | `/api/application/nodes/${nodeId}`
248 | );
249 | };
250 | }
251 |
--------------------------------------------------------------------------------
/src/application/methods/server.ts:
--------------------------------------------------------------------------------
1 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
2 | import {
3 | EditServerBuild,
4 | EditServerDetails,
5 | EditServerStartup,
6 | Server,
7 | ServerAttributes,
8 | ServerEnvironment,
9 | ServerFilterInput,
10 | ServerIncludesInput,
11 | Servers
12 | } from '../interfaces/Server';
13 | import { Application } from '../index';
14 |
15 | export class serverMethods {
16 | constructor(private readonly application: Application) {}
17 | /**
18 | * @internal
19 | */
20 | private getServers = async (options: MakeOpts): Promise => {
21 | return this.application.request(
22 | 'GET',
23 | null,
24 | '',
25 | `/api/application/servers${makeOptions(options)}`
26 | );
27 | };
28 | /**
29 | * @param options - Include information about server relationships
30 | * @param filter - Filter Servers by specific fields and values
31 | * @returns Array of server
32 | * @example
33 | * ```ts
34 | * const res = await app.getAllServers() // res = Server[]
35 | * ```
36 | * @example
37 | * ```ts
38 | * app.getAllServers().then((res) => console.log(res)) // res = Server[]
39 | * ```
40 | */
41 | public getAllServers = async (
42 | options?: ServerIncludesInput,
43 | filter?: ServerFilterInput
44 | ): Promise => {
45 | return await paginate(this.getServers.bind(this), {
46 | includes: { ...options },
47 | filter: filter
48 | });
49 | };
50 | /**
51 | * @param serverId - The server ID to get the details of.
52 | * @param options - Include information about server relationships
53 | * @returns Server information
54 | * @example
55 | * ```ts
56 | * const res = await app.getServerInfo(1) // res = ServerAttributes
57 | * ```
58 | * @example
59 | * ```ts
60 | * app.getServerInfo(1).then((res) => console.log(res)) // res = ServerAttributes
61 | * ```
62 | */
63 | public getServerInfo = async (
64 | serverId: number,
65 | options?: ServerIncludesInput
66 | ): Promise => {
67 | return this.application.request(
68 | 'GET',
69 | null,
70 | 'attributes',
71 | `/api/application/servers/${serverId}${makeOptions({
72 | includes: { ...options }
73 | })}`
74 | );
75 | };
76 | /**
77 | * @param serverId - The external server ID to get the details of.
78 | * @param options - Include information about server relationships
79 | * @returns Server information
80 | * @example
81 | * ```ts
82 | * const res = await app.getServerInfoByExtId('MC_SERVER') // res = ServerAttributes
83 | * ```
84 | * @example
85 | * ```ts
86 | * app.getServerInfoByExtId('GAMER_SERVER').then((res) => console.log(res)) // res = ServerAttributes
87 | * ```
88 | */
89 | public getServerInfoByExtId = async (
90 | serverId: string,
91 | options?: ServerIncludesInput
92 | ): Promise => {
93 | return this.application.request(
94 | 'GET',
95 | null,
96 | 'attributes',
97 | `/api/application/servers/external/${serverId}${makeOptions({
98 | includes: { ...options }
99 | })}`
100 | );
101 | };
102 | /**
103 | * @param serverId - The server ID to get the details of.
104 | * @param options - The options to edit
105 | * @returns Server information
106 | * @example
107 | * ```ts
108 | * const res = await app.editServerDetails(1, 'Mc server') // res = ServerAttributes
109 | * ```
110 | * @example
111 | * ```ts
112 | * app.editServerDetails(1, undefined, undefined, 'MC_SERVER').then((res) => console.log(res)) // res = ServerAttributes
113 | * ```
114 | */
115 | public editServerDetails = async (
116 | serverId: number,
117 | options: EditServerDetails
118 | ): Promise => {
119 | const server = await this.getServerInfo(serverId);
120 | return this.application.request(
121 | 'PATCH',
122 | {
123 | name: options.name ?? server.name,
124 | user: options.userId != undefined ? options.userId : server.user,
125 | external_id: options.externalId ?? server.external_id,
126 | description: options.description ?? server.description
127 | },
128 | 'attributes',
129 | `/api/application/servers/${serverId}/details${makeOptions({
130 | includes: { ...options.options }
131 | })}`
132 | );
133 | };
134 | /**
135 | * @param serverId - The server ID to get the details of.
136 | * @param options - The options to edit
137 | * @returns Server information
138 | * @example
139 | * ```ts
140 | * const res = await app.editServerBuild(1, undefined, undefined, [5, 6]) // res = ServerAttributes
141 | * ```
142 | * @example
143 | * ```ts
144 | * app.editServerBuild(1, undefined, [1, 3]).then((res) => console.log(res)) // res = ServerAttributes
145 | * ```
146 | */
147 | public editServerBuild = async (
148 | serverId: number,
149 | options: EditServerBuild
150 | ): Promise => {
151 | const server = await this.getServerInfo(serverId);
152 | return this.application.request(
153 | 'PATCH',
154 | {
155 | allocation:
156 | options.allocationId != undefined
157 | ? options.allocationId
158 | : server.allocation,
159 | add_allocations: options.addAllocations ?? [],
160 | remove_allocations: options.removeAllocations ?? [],
161 | memory:
162 | options.memory != undefined ? options.memory : server.limits.memory,
163 | swap: options.swap != undefined ? options.swap : server.limits.swap,
164 | disk: options.disk != undefined ? options.disk : server.limits.disk,
165 | io: options.io != undefined ? options.io : server.limits.io,
166 | cpu: options.cpu != undefined ? options.cpu : server.limits.cpu,
167 | threads:
168 | options.threads != undefined
169 | ? options.threads
170 | : server.limits.threads,
171 | feature_limits: {
172 | databases:
173 | options.databases != undefined
174 | ? options.databases
175 | : server.feature_limits.databases,
176 | allocations:
177 | options.allocations != undefined
178 | ? options.allocations
179 | : server.feature_limits.allocations,
180 | backups:
181 | options.backups != undefined
182 | ? options.backups
183 | : server.feature_limits.backups
184 | }
185 | },
186 | 'attributes',
187 | `/api/application/servers/${serverId}/build${makeOptions({
188 | includes: { ...options.options }
189 | })}`
190 | );
191 | };
192 | /**
193 | * @param serverId - The external server ID to get the details of.
194 | * @param startup - The new startup command
195 | * @param environment - Servers environment variables. REQUIRED!
196 | * @param egg - The new egg you want to use
197 | * @param image - The new docker image you want to use
198 | * @param skip_scripts - Skip install script boolean (FALSE by default!)
199 | * @param options - Include information about server relationships
200 | * @returns Server information
201 | * @example
202 | * ```ts
203 | * const res = await app.editServerStartup(1, 'node index.js') // res = ServerAttributes
204 | * ```
205 | * @example
206 | * ```ts
207 | * app.editServerStartup(1, 'node index.js').then((res) => console.log(res)) // res = ServerAttributes
208 | * ```
209 | */
210 | public editServerStartup = async (
211 | serverId: number,
212 | options: EditServerStartup
213 | ): Promise => {
214 | const server = await this.getServerInfo(serverId, { variables: true });
215 | const envVars: Record = {};
216 | if (options.environment) {
217 | const env = options.environment;
218 | const givenEnvVars = Object.keys(options.environment);
219 | server.relationships?.variables?.data.forEach((envVar) => {
220 | const envVariable = envVar.attributes.env_variable;
221 | if (givenEnvVars.includes(envVariable)) {
222 | envVars[envVariable] = env[envVariable];
223 | } else if (envVar.attributes.server_value) {
224 | envVars[envVariable] = envVar.attributes.server_value;
225 | } else if (envVar.attributes.default_value) {
226 | envVars[envVariable] = envVar.attributes.default_value;
227 | } else if (envVar.attributes.rules.includes('nullable')) {
228 | envVars[envVariable] = '';
229 | } else {
230 | throw new Error(
231 | `Environment variable ${envVariable} was not defined!`
232 | );
233 | }
234 | });
235 | }
236 | return this.application.request(
237 | 'PATCH',
238 | {
239 | startup: options.startup ?? server.container.startup_command,
240 | environment: options.environment
241 | ? envVars
242 | : server.container.environment,
243 | egg: options.egg != undefined ? options.egg : server.egg,
244 | image: options.image ?? server.container.image,
245 | skip_scripts: options.skip_scripts ?? false
246 | },
247 | 'attributes',
248 | `/api/application/servers/${serverId}/startup${makeOptions({
249 | includes: { ...options.options }
250 | })}`
251 | );
252 | };
253 | /**
254 | * @param name -Name of server to create
255 | * @param ownerId - User ID of who should own this server
256 | * @param description - Description of server
257 | * @param nestId - ID of the nest to use when making a server
258 | * @param eggId - Egg ID to use when installing the server
259 | * @param environment - Servers environment variables. Some are REQUIRED! If there is a default value and none is provided default is used!
260 | * @param cpu - Amount of cpu resources to give (1 core = 100) (0 unlimited)
261 | * @param ram - Amount of memory resources to give (1024 = 1GB) (0 unlimited)
262 | * @param disk - Amount of disk space to give (1024 = 1GB) (0 unlimited)
263 | * @param amountOfDatabases - The max amount of databases a server can use
264 | * @param amountOfAllocations - The max amount of allocation(s) a server can use
265 | * @param amountOfBackups - The max amount of backups a server can use
266 | * @param startupCmd - The command to use when starting this server
267 | * @param dockerImage - The image to use from Docker
268 | * @param swap - The amount of Swap the server has
269 | * @param io - Set this to 500.
270 | * @param options - Include information about server relationships
271 | * @returns Returns the created server object
272 | * @example
273 | * ```ts
274 | * const res = await app.createServer('BUNGEE', 1, 'BUNGEE SERVER', 1, 1) // res = ServerAttributes
275 | * ```
276 | * @example
277 | * ```ts
278 | * app.createServer('BUNGEE', 1, 'BUNGEE SERVER', 1, 1).then((res) => console.log(res)) // res = ServerAttributes
279 | * ```
280 | */
281 | public createServer = async (
282 | name: string,
283 | ownerId: number,
284 | description: string,
285 | nestId: number,
286 | eggId: number,
287 | defaultAllocationId: number,
288 | addAllocationIds: number[] = [],
289 | environment?: ServerEnvironment,
290 | cpu = 0,
291 | ram = 0,
292 | disk = 0,
293 | amountOfDatabases = 0,
294 | amountOfAllocations = 0,
295 | amountOfBackups = 0,
296 | startupCmd?: string,
297 | dockerImage?: string,
298 | swap = 0,
299 | io = 500,
300 | startOnCompletion = false,
301 | options?: ServerIncludesInput // Databases are always empty
302 | ): Promise => {
303 | const egg = await this.application.getEggInfo(nestId, eggId, {
304 | variables: true
305 | });
306 | const envVars: Record = {};
307 | let givenEnvVars: string[] = [];
308 | if (environment) givenEnvVars = Object.keys(environment);
309 | egg.relationships?.variables?.data.forEach(
310 | (envVar: {
311 | attributes: {
312 | env_variable: string;
313 | rules: string;
314 | default_value: string;
315 | };
316 | }) => {
317 | const envVariable = envVar.attributes.env_variable;
318 | if (givenEnvVars.includes(envVariable)) {
319 | envVars[envVariable] = environment?.[envVariable];
320 | } else if (envVar.attributes.rules.includes('nullable')) {
321 | envVars[envVariable] = '';
322 | } else if (envVar.attributes.default_value) {
323 | envVars[envVariable] = envVar.attributes.default_value;
324 | } else {
325 | throw new Error(
326 | `Environment variable ${envVariable} was not defined!`
327 | );
328 | }
329 | }
330 | );
331 | return this.application.request(
332 | 'POST',
333 | {
334 | name: name,
335 | user: ownerId,
336 | description: description,
337 | egg: eggId,
338 | pack: nestId,
339 | docker_image: dockerImage ? dockerImage : egg.docker_image,
340 | startup: startupCmd ? startupCmd : egg.startup,
341 | limits: {
342 | memory: ram,
343 | swap: swap,
344 | disk: disk,
345 | io: io,
346 | cpu: cpu
347 | },
348 | feature_limits: {
349 | databases: amountOfDatabases,
350 | allocations: amountOfAllocations,
351 | backups: amountOfBackups
352 | },
353 | environment: envVars,
354 | allocation: {
355 | default: defaultAllocationId,
356 | allocation_additional: addAllocationIds ?? []
357 | },
358 | start_on_completion: startOnCompletion,
359 | skip_scripts: false,
360 | oom_disabled: true
361 | },
362 | 'attributes',
363 | `/api/application/servers${makeOptions({
364 | includes: { ...options }
365 | })}`
366 | );
367 | };
368 | /**
369 | * @param internalId - Internal ID of the server to delete
370 | * @param forceDelete - Boolean if forcefully delete a server
371 | * @returns If successful returns Successfully deleted!
372 | * @example
373 | * ```ts
374 | * const res = await app.deleteServer(1) // res = Successfully deleted!
375 | * ```
376 | * @example
377 | * ```ts
378 | * app.deleteServer(1, true).then((res) => console.log(res)) // res = Successfully deleted!
379 | * ```
380 | */
381 | public deleteServer = async (
382 | internalId: number,
383 | forceDelete = false
384 | ): Promise => {
385 | let force = '';
386 | if (forceDelete) force = '/force';
387 | return this.application.request(
388 | 'DELETE',
389 | null,
390 | 'Successfully deleted!',
391 | `/api/application/servers/${internalId}${force}`
392 | );
393 | };
394 | /**
395 | * @param internalId - Internal ID of the server to suspend
396 | * @returns If successful returns Successfully suspended!
397 | * @example
398 | * ```ts
399 | * const res = await app.suspendServer(1) // res = Successfully suspended!
400 | * ```
401 | * @example
402 | * ```ts
403 | * app.suspendServer(1).then((res) => console.log(res)) // res = Successfully suspended!
404 | * ```
405 | */
406 | public suspendServer = (internalID: number): Promise => {
407 | return this.application.request(
408 | 'POST',
409 | null,
410 | 'Successfully suspended!',
411 | `/api/application/servers/${internalID}/suspend`
412 | );
413 | };
414 | /**
415 | * @param internalId - Internal ID of the server to suspend
416 | * @returns If successful returns Successfully unsuspended!
417 | * @example
418 | * ```ts
419 | * const res = await app.unSuspendServer(1) // res = Successfully unsuspended!
420 | * ```
421 | * @example
422 | * ```ts
423 | * app.unSuspendServer(1).then((res) => console.log(res)) // res = Successfully unsuspended!
424 | * ```
425 | */
426 | public unSuspendServer = (internalID: number): Promise => {
427 | return this.application.request(
428 | 'POST',
429 | null,
430 | 'Successfully unsuspended!',
431 | `/api/application/servers/${internalID}/unsuspend`
432 | );
433 | };
434 | /**
435 | * @param internalId - Internal ID of the server to reinstall
436 | * @returns If successful returns Successfully reinstalled!
437 | * @example
438 | * ```ts
439 | * const res = await app.reinstallServer(1) // res = Successfully reinstalled!
440 | * ```
441 | * @example
442 | * ```ts
443 | * app.reinstallServer(1).then((res) => console.log(res)) // res = Successfully reinstalled!
444 | * ```
445 | */
446 | public reinstallServer = (internalID: number): Promise => {
447 | return this.application.request(
448 | 'POST',
449 | null,
450 | 'Successfully reinstalled!',
451 | `/api/application/servers/${internalID}/reinstall`
452 | );
453 | };
454 | }
455 |
--------------------------------------------------------------------------------
/src/application/methods/user.ts:
--------------------------------------------------------------------------------
1 | import { Application } from '../index';
2 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
3 | import {
4 | EditUserOptions,
5 | User,
6 | UserAttributes,
7 | UserFilterInput,
8 | UserIncludeInput,
9 | Users
10 | } from '../interfaces/User';
11 |
12 | export class userMethods {
13 | constructor(private readonly application: Application) {}
14 | /**
15 | * @internal
16 | */
17 | private getUsers = async (options: MakeOpts): Promise => {
18 | return this.application.request(
19 | 'GET',
20 | null,
21 | '',
22 | `/api/application/users${makeOptions(options)}`
23 | );
24 | };
25 | /**
26 | * @param options - Include information about relationships
27 | * @param filter - Filter Users by specific fields and values
28 | * @returns Array of users
29 | * @example
30 | * ```ts
31 | * const res = await app.getAllUsers() // res = User[]
32 | * ```
33 | * @example
34 | * ```ts
35 | * app.getAllUsers().then((res) => console.log(res)) // res = User[]
36 | * ```
37 | */
38 | public getAllUsers = async (
39 | options?: UserIncludeInput,
40 | filter?: UserFilterInput
41 | ): Promise => {
42 | return await paginate(this.getUsers.bind(this), {
43 | includes: { ...options },
44 | filter: filter
45 | });
46 | };
47 | /**
48 | * @param userId - The user id to get information about
49 | * @param options - Include information about relationships
50 | * @returns User information
51 | * @example
52 | * ```ts
53 | * const res = await app.getUserInfo(1) // res = UserAttributes
54 | * ```
55 | * @example
56 | * ```ts
57 | * app.getUserInfo(1).then((res) => console.log(res)) // res = UserAttributes
58 | * ```
59 | */
60 | public getUserInfo = async (
61 | userId: number,
62 | options?: UserIncludeInput
63 | ): Promise => {
64 | return this.application.request(
65 | 'GET',
66 | null,
67 | 'attributes',
68 | `/api/application/users/${userId}${makeOptions({
69 | includes: { ...options }
70 | })}`
71 | );
72 | };
73 | /**
74 | * @param userId - The external user id to get information about
75 | * @param options - Include information about relationships
76 | * @returns User information
77 | * @example
78 | * ```ts
79 | * const res = await app.getUserInfoByExtId(1) // res = UserAttributes
80 | * ```
81 | * @example
82 | * ```ts
83 | * app.getUserInfoByExtId(1).then((res) => console.log(res)) // res = UserAttributes
84 | * ```
85 | */
86 | public getUserInfoByExtId = async (
87 | userId: string,
88 | options?: UserIncludeInput
89 | ): Promise => {
90 | return this.application.request(
91 | 'GET',
92 | null,
93 | 'attributes',
94 | `/api/application/users/external/${userId}${makeOptions({
95 | includes: { ...options }
96 | })}`
97 | );
98 | };
99 | /**
100 | * @param username - The username of the user
101 | * @param firstName - The first name of the user
102 | * @param lastName - The last name of the user
103 | * @param email - The email address of the user
104 | * @param password - The password of the user
105 | * @param isAdmin - Is the user admin (default false)
106 | * @param language - The language of the user (default en)
107 | * @param externalId - The external id of user
108 | * @param options - Include information about relationships
109 | * @returns User information
110 | * @example
111 | * ```ts
112 | * const res = await app.createUser('linux123123', 'Linus', 'ADMIN', 'api@gmail.com') // res = UserAttributes
113 | * ```
114 | * @example
115 | * ```ts
116 | * app.createUser('linux123123', 'Linus', 'ADMIN', 'api@gmail.com').then((res) => console.log(res)) // res = UserAttributes
117 | * ```
118 | */
119 | public createUser = async (
120 | username: string,
121 | firstName: string,
122 | lastName: string,
123 | email: string,
124 | password = '',
125 | isAdmin = false,
126 | language = 'en',
127 | externalId?: string
128 | ): Promise => {
129 | return this.application.request(
130 | 'POST',
131 | {
132 | email: email,
133 | username: username,
134 | first_name: firstName,
135 | last_name: lastName,
136 | language: language,
137 | root_admin: isAdmin,
138 | password: password,
139 | external_id: externalId ? externalId : ''
140 | },
141 | 'attributes',
142 | `/api/application/users`
143 | );
144 | };
145 | /**
146 | * @param userId - The user id of the user to edit
147 | * @param options - Options to edit user
148 | * @returns User information
149 | * @example
150 | * ```ts
151 | * const res = await app.editUser(1, 'linux123123', undefined, 'ADMIN_LAST) // res = UserAttributes
152 | * ```
153 | * @example
154 | * ```ts
155 | * app.editUser(1, undefined, 'Linux').then((res) => console.log(res)) // res = UserAttributes
156 | * ```
157 | */
158 | public editUser = async (
159 | userId: number,
160 | options: EditUserOptions
161 | ): Promise => {
162 | const user = await this.getUserInfo(userId);
163 | return this.application.request(
164 | 'PATCH',
165 | {
166 | email: options.email ?? user.email,
167 | username: options.username ?? user.username,
168 | first_name: options.firstName ?? user.first_name,
169 | last_name: options.lastName ?? user.last_name,
170 | language: options.language ?? user.language,
171 | root_admin: options.isAdmin ?? user.root_admin,
172 | password: options.password ?? '',
173 | external_id: options.externalId ?? user.external_id
174 | },
175 | 'attributes',
176 | `/api/application/users/${userId}${makeOptions({
177 | includes: { ...options.options }
178 | })}`
179 | );
180 | };
181 | /**
182 | * @param userId - The user id of the user to delete
183 | * @returns If successful returns Successfully deleted!
184 | * @example
185 | * ```ts
186 | * const res = await app.deleteUser(1) // res = Successfully deleted!
187 | * ```
188 | * @example
189 | * ```ts
190 | * app.deleteUser(1).then((res) => console.log(res)) // res = Successfully deleted!
191 | * ```
192 | */
193 | public deleteUser = async (userId: number): Promise => {
194 | return this.application.request(
195 | 'DELETE',
196 | null,
197 | 'Successfully deleted!',
198 | `/api/application/users/${userId}`
199 | );
200 | };
201 | }
202 |
--------------------------------------------------------------------------------
/src/client/Websocket.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientWebsocket */
2 |
3 | import { EventEmitter } from 'node:events';
4 | import { WebsocketAuthData } from './interfaces/WebsocketAuthData';
5 | import { JSPteroAPIError } from '../modules/Error';
6 | import { Socket } from '../modules/Socket';
7 |
8 | const reconnectErrors = [
9 | 'jwt: exp claim is invalid',
10 | 'jwt: created too far in past (denylist)'
11 | ];
12 |
13 | export class WebsocketClient extends EventEmitter {
14 | constructor(
15 | errorHandler: (error: JSPteroAPIError) => void,
16 | auth: WebsocketAuthData,
17 | private getToken: () => Promise
18 | ) {
19 | super();
20 | // Allow 100 listeners for this instance
21 | this.setMaxListeners(100);
22 | this.updateToken = ((
23 | getToken: () => Promise,
24 | socket: WebsocketClient
25 | ) => {
26 | if (this.isUpdating) {
27 | return;
28 | }
29 |
30 | this.isUpdating = true;
31 |
32 | try {
33 | getToken().then((data) => socket.setToken(data.token));
34 | } catch (e) {
35 | if (e instanceof JSPteroAPIError) {
36 | if (
37 | e.ERRORS[0] ===
38 | 'This server is currently suspended and the functionality requested is unavailable.'
39 | ) {
40 | return this.close(409, 'Suspended');
41 | }
42 | return errorHandler(e);
43 | }
44 | throw e;
45 | }
46 | }).bind(undefined, this.getToken, this);
47 |
48 | this.setToken(auth.token).connect(auth.socket);
49 |
50 | // Set listerners
51 | this.on('daemon error', (message) => {
52 | console.error(message);
53 | });
54 |
55 | this.on('token expiring', () => this.updateToken());
56 | this.on('token expired', () => this.updateToken());
57 | this.on('jwt error', (error: string) => {
58 | if (reconnectErrors.find((v) => error.toLowerCase().indexOf(v) >= 0)) {
59 | this.updateToken();
60 | } else {
61 | throw new Error(error);
62 | }
63 | });
64 | this.on('transfer status', (status: string) => {
65 | if (status === 'starting' || status === 'success') {
66 | return;
67 | }
68 |
69 | // This code forces a reconnection to the websocket which will connect us to the target node instead of the source node
70 | // in order to be able to receive transfer logs from the target node.
71 | this.close();
72 | this.open();
73 | });
74 | }
75 |
76 | private isUpdating = false;
77 |
78 | // Timer instance for this socket.
79 | private timer!: NodeJS.Timeout;
80 |
81 | // The backoff for the timer, in milliseconds.
82 | private backoff = 5000;
83 |
84 | // The socket instance being tracked.
85 | private socket: Socket | null = null;
86 |
87 | // The URL being connected to for the socket.
88 | private url: string | null = null;
89 |
90 | // The authentication token passed along with every request to the Daemon.
91 | // By default this token expires every 15 minutes and must therefore be
92 | // refreshed at a pretty continuous interval. The socket server will respond
93 | // with "token expiring" and "token expired" events when approaching 3 minutes
94 | // and 0 minutes to expiry.
95 | private token = '';
96 |
97 | // Connects to the websocket instance and sets the token for the initial request.
98 | private connect(url: string): this {
99 | this.url = url;
100 |
101 | this.timer && clearTimeout(this.timer);
102 |
103 | // Close socket if needed
104 | if (this.socket?.ws.OPEN) {
105 | this.close();
106 | }
107 |
108 | this.socket = new Socket(this.url, {
109 | onmessage: (e) => {
110 | try {
111 | const { event, args } = JSON.parse(e.data.toString());
112 | args ? this.emit(event, ...args) : this.emit(event);
113 | } catch (ex) {
114 | console.warn('Failed to parse incoming websocket message.', ex);
115 | }
116 | },
117 | onopen: () => {
118 | // Clear the timers, we managed to connect just fine.
119 | this.timer && clearTimeout(this.timer);
120 | this.backoff = 5000;
121 |
122 | this.emit('SOCKET_OPEN');
123 | this.authenticate();
124 | },
125 | onreconnect: () => {
126 | this.emit('SOCKET_RECONNECT');
127 | this.authenticate();
128 | },
129 | onclose: () => this.emit('SOCKET_CLOSE'),
130 | onerror: (event) => {
131 | if (
132 | event.message ===
133 | 'WebSocket was closed before the connection was established'
134 | )
135 | return;
136 | throw new Error(event.message);
137 | },
138 | onmaximum: () => {
139 | return;
140 | }
141 | });
142 |
143 | this.timer = setTimeout(() => {
144 | this.backoff = this.backoff + 2500 >= 20000 ? 20000 : this.backoff + 2500;
145 | this.socket && this.socket.close(undefined, 'timeout');
146 | clearTimeout(this.timer);
147 |
148 | // Re-attempt connecting to the socket.
149 | this.connect(url);
150 | }, this.backoff);
151 |
152 | return this;
153 | }
154 |
155 | private updateToken!: () => void;
156 |
157 | // Sets the authentication token to use when sending commands back and forth
158 | // between the websocket instance.
159 | private setToken(token: string, isUpdate = false): this {
160 | this.token = token;
161 |
162 | if (isUpdate) {
163 | this.authenticate();
164 | }
165 |
166 | return this;
167 | }
168 |
169 | private authenticate(): void {
170 | if (this.url && this.token) {
171 | this.send('auth', this.token);
172 | }
173 | }
174 |
175 | public close(code?: number, reason?: string): void {
176 | this.url = null;
177 | this.token = '';
178 | this.socket && this.socket.close(code, reason);
179 | }
180 |
181 | private open(): void {
182 | this.socket && this.socket.open();
183 | }
184 |
185 | public send(event: string, payload?: string | string[]): void {
186 | this.socket &&
187 | this.socket.send(
188 | JSON.stringify({
189 | event,
190 | args: Array.isArray(payload) ? payload : [payload]
191 | })
192 | );
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/src/client/index.ts:
--------------------------------------------------------------------------------
1 | import { Request } from '../modules/Request';
2 | import { serverMethods } from './methods/server';
3 | import { consoleMethods } from './methods/console';
4 | import { fileMethods } from './methods/file';
5 | import { databaseMethods } from './methods/database';
6 | import { accountMethods } from './methods/account';
7 | import { scheduleMethods } from './methods/schedule';
8 | import { JSPteroAPIError } from '../modules/Error';
9 | import { networkMethods } from './methods/network';
10 | import { subUserMethods } from './methods/subUser';
11 | import { backupMethods } from './methods/backups';
12 | import { settingsMethods } from './methods/settings';
13 |
14 | class Client {
15 | /**
16 | * @param host - Panels address
17 | * @param key - Api key to use
18 | * @param errorHandler - A custom function to handle errors
19 | * @param fast - Fast login (No credential check)
20 | */
21 | public constructor(
22 | private host: string,
23 | private key: string,
24 | private errorHandler = (error: JSPteroAPIError): void => {
25 | throw error;
26 | },
27 | fast = false
28 | ) {
29 | host = host.trim();
30 | if (host.endsWith('/')) host = host.slice(0, -1);
31 | this.host = host;
32 | this.request = new Request(this.host, this.key, this.errorHandler).request;
33 | // Server
34 | const servermethods = new serverMethods(this);
35 | this.getAllServers = servermethods.getAllServers;
36 | this.getServerInfo = servermethods.getServerInfo;
37 | this.getServerResources = servermethods.getServerResources;
38 | this.sendCommand = servermethods.sendCommand;
39 | this.setPowerState = servermethods.setPowerState;
40 | // Console
41 | const consolemethods = new consoleMethods(this, this.errorHandler);
42 | this.startConsoleConnection = consolemethods.startConsoleConnection;
43 | // File
44 | const filemethods = new fileMethods(this);
45 | this.getAllFiles = filemethods.getAllFiles;
46 | this.getFileContents = filemethods.getFileContents;
47 | this.writeFile = filemethods.writeFile;
48 | this.renameFile = filemethods.renameFile;
49 | this.copyFile = filemethods.copyFile;
50 | this.getFileDownloadLink = filemethods.getFileDownloadLink;
51 | this.compressFile = filemethods.compressFile;
52 | this.decompressFile = filemethods.decompressFile;
53 | this.deleteFile = filemethods.deleteFile;
54 | this.createFolder = filemethods.createFolder;
55 | this.getFileUploadLink = filemethods.getFileUploadLink;
56 | // Database
57 | const databasemethods = new databaseMethods(this);
58 | this.getAllDatabases = databasemethods.getAllDatabases;
59 | this.createDatabase = databasemethods.createDatabase;
60 | this.deleteDatabase = databasemethods.deleteDatabase;
61 | this.rotateDatabasePass = databasemethods.rotateDatabasePass;
62 | // Account
63 | const accountmethods = new accountMethods(this);
64 | this.getAllPermissions = accountmethods.getAllPermissions;
65 | this.getAccountInfo = accountmethods.getAccountInfo;
66 | this.getAccount2FADetails = accountmethods.getAccount2FADetails;
67 | this.enable2FA = accountmethods.enable2FA;
68 | this.updateEmail = accountmethods.updateEmail;
69 | this.updatePassword = accountmethods.updatePassword;
70 | this.getAllApiKeys = accountmethods.getAllApiKeys;
71 | this.createApiKey = accountmethods.createApiKey;
72 | this.deleteApiKey = accountmethods.deleteApiKey;
73 | // Schedule
74 | const schedulemethods = new scheduleMethods(this);
75 | this.getAllSchedules = schedulemethods.getAllSchedules;
76 | this.createSchedule = schedulemethods.createSchedule;
77 | this.getScheduleInfo = schedulemethods.getScheduleInfo;
78 | this.editSchedule = schedulemethods.editSchedule;
79 | // Network
80 | const networkmethods = new networkMethods(this);
81 | this.getAllAlocations = networkmethods.getAllAlocations;
82 | this.assignAllocation = networkmethods.assignAllocation;
83 | this.setAllocationNote = networkmethods.setAllocationNote;
84 | this.setAllocationPrimary = networkmethods.setAllocationPrimary;
85 | this.deleteAllocation = networkmethods.deleteAllocation;
86 | // SubUsers
87 | const subusermethods = new subUserMethods(this);
88 | this.getAllSubUsers = subusermethods.getAllSubUsers;
89 | this.createSubUser = subusermethods.createSubUser;
90 | this.getSubUserInfo = subusermethods.getSubUserInfo;
91 | this.updateSubUserPermissions = subusermethods.updateSubUserPermissions;
92 | this.deleteSubUser = subusermethods.deleteSubUser;
93 | // Backups
94 | const backupmethods = new backupMethods(this);
95 | this.getAllBackups = backupmethods.getAllBackups;
96 | this.createBackup = backupmethods.createBackup;
97 | this.getBackupInfo = backupmethods.getBackupInfo;
98 | this.getBackupDownloadLink = backupmethods.getBackupDownloadLink;
99 | this.deleteBackup = backupmethods.deleteBackup;
100 | this.toggleLockBackup = backupmethods.toggleLockBackup;
101 | this.restoreBackup = backupmethods.restoreBackup;
102 | // Settings
103 | const settingsmethods = new settingsMethods(this);
104 | this.renameServer = settingsmethods.renameServer;
105 | this.reinstallServer = settingsmethods.reinstallServer;
106 |
107 | if (!fast) this.testAPI();
108 | }
109 | /**
110 | * @param throwError - Whether to throw an error or return bool
111 | * @remarks Will not work if using custom error handler.
112 | */
113 | public testAPI = async (throwError = true): Promise => {
114 | try {
115 | await this.getAllServers();
116 | return true;
117 | } catch (e) {
118 | if (e instanceof JSPteroAPIError) {
119 | if (throwError) {
120 | if (e.HTML_STATUS === 403) e.ERRORS = ['Invalid Client API key'];
121 | throw e;
122 | }
123 | return false;
124 | } else {
125 | if (throwError) throw e;
126 | return false;
127 | }
128 | }
129 | };
130 |
131 | /**
132 | @internal
133 | */
134 | public request;
135 |
136 | // Get
137 | public getAllServers;
138 | public getServerInfo;
139 | public getServerResources;
140 | public getAllPermissions;
141 | public getAllDatabases;
142 | public getAllFiles;
143 | public getFileContents;
144 | public getFileDownloadLink;
145 | public getFileUploadLink;
146 | public getAccountInfo;
147 | public getAccount2FADetails;
148 | public getAllApiKeys;
149 | public getAllSchedules;
150 | public getScheduleInfo;
151 | public getAllAlocations;
152 | public getAllSubUsers;
153 | public getSubUserInfo;
154 | public getAllBackups;
155 | public getBackupInfo;
156 | public getBackupDownloadLink;
157 | // POST
158 | public sendCommand;
159 | public setPowerState;
160 | public createDatabase;
161 | public rotateDatabasePass;
162 | public copyFile;
163 | public writeFile;
164 | public compressFile;
165 | public decompressFile;
166 | public deleteFile;
167 | public createFolder;
168 | public enable2FA;
169 | public createApiKey;
170 | public createSchedule;
171 | public editSchedule;
172 | public assignAllocation;
173 | public setAllocationNote;
174 | public setAllocationPrimary;
175 | public createSubUser;
176 | public updateSubUserPermissions;
177 | public createBackup;
178 | public renameServer;
179 | public reinstallServer;
180 | public toggleLockBackup;
181 | public restoreBackup;
182 | // Delete
183 | public deleteDatabase;
184 | public deleteApiKey;
185 | public deleteAllocation;
186 | public deleteSubUser;
187 | public deleteBackup;
188 | // PUT
189 | public renameFile;
190 | public updateEmail;
191 | public updatePassword;
192 |
193 | public startConsoleConnection;
194 | }
195 |
196 | export { Client };
197 |
--------------------------------------------------------------------------------
/src/client/interfaces/Allocation.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientAllocation */
2 |
3 | export interface Allocation {
4 | id: number;
5 | ip: string;
6 | alias: string | null;
7 | port: number;
8 | notes: string | null;
9 | isDefault: boolean;
10 | }
11 |
--------------------------------------------------------------------------------
/src/client/interfaces/ApiKey.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientApiKey */
2 |
3 | export interface ApiKeyAttributes {
4 | identifier: string;
5 | description: string;
6 | allowed_ips: string[];
7 | last_used_at: string | null;
8 | created_at: string;
9 | }
10 |
11 | export interface ApiKeyMeta {
12 | secret_token: string;
13 | }
14 |
15 | export interface ApiKey {
16 | object: 'api_key';
17 | attributes: ApiKeyAttributes;
18 | meta?: ApiKeyMeta;
19 | }
20 |
21 | export interface ApiKeyList {
22 | object: 'list';
23 | data: ApiKey[];
24 | }
25 |
--------------------------------------------------------------------------------
/src/client/interfaces/Backups.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientBackup */
2 |
3 | export interface BackupAttributes {
4 | uuid: string;
5 | name: string;
6 | ignored_files: string[];
7 | checksum: string;
8 | bytes: number;
9 | created_at: string;
10 | completed_at: string;
11 | is_successful: boolean;
12 | is_locked: boolean;
13 | }
14 |
15 | export interface Backup {
16 | object: 'backup';
17 | attributes: BackupAttributes;
18 | }
19 |
20 | export interface Backups {
21 | object: 'list';
22 | data: Backup[];
23 | meta: {
24 | pagination: {
25 | total: number;
26 | count: number;
27 | per_page: number;
28 | current_page: number;
29 | total_pages: number;
30 | };
31 | };
32 | }
33 |
--------------------------------------------------------------------------------
/src/client/interfaces/Database.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientDatabase */
2 | export interface DatabaseIncludeInput {
3 | password?: boolean;
4 | }
5 |
6 | export interface DatabaseAttributesHost {
7 | address: string;
8 | port: number;
9 | }
10 |
11 | export interface DatabaseAttributes {
12 | id: string;
13 | host: DatabaseAttributesHost;
14 | name: string;
15 | username: string;
16 | connections_from: string;
17 | max_connections: number;
18 | relationships?: DatabaseRelationships;
19 | }
20 | export interface DatabaseRelationships {
21 | password: DatabasePassword;
22 | }
23 |
24 | export interface DatabasePassword {
25 | object: string;
26 | attributes: DatabasePasswordAttributes;
27 | }
28 |
29 | export interface DatabasePasswordAttributes {
30 | password: string;
31 | }
32 |
33 | export interface Database {
34 | object: string;
35 | attributes: DatabaseAttributes;
36 | }
37 |
--------------------------------------------------------------------------------
/src/client/interfaces/Permissions.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientPermissions */
2 | export interface Permissions {
3 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
4 | permissions: Record;
5 | }
6 |
--------------------------------------------------------------------------------
/src/client/interfaces/Schedule.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientSchedule */
2 |
3 | export interface ScheduleCron {
4 | day_of_week: string;
5 | day_of_month: string;
6 | hour: string;
7 | month: string;
8 | minute: string;
9 | }
10 |
11 | export interface ScheduleTaskAttributes {
12 | id: number;
13 | sequence_id: number;
14 | action: string;
15 | payload: string;
16 | time_offset: number;
17 | is_queued: boolean;
18 | continue_on_failure: boolean;
19 | created_at: string;
20 | updated_at: string;
21 | }
22 |
23 | export interface ScheduleTask {
24 | object: 'schedule_task';
25 | attributes: ScheduleTaskAttributes;
26 | }
27 |
28 | export interface ScheduleTasks {
29 | object: string;
30 | data: ScheduleTask[];
31 | }
32 |
33 | export interface ScheduleRelationships {
34 | tasks: ScheduleTasks;
35 | }
36 |
37 | export interface ScheduleAttributes {
38 | id: number;
39 | name: string;
40 | cron: ScheduleCron;
41 | is_active: boolean;
42 | is_processing: boolean;
43 | last_run_at: string | null;
44 | next_run_at: string;
45 | created_at: string;
46 | updated_at: string;
47 | relationships: ScheduleRelationships;
48 | }
49 |
50 | export interface Schedule {
51 | object: 'server_schedule';
52 | attributes: ScheduleAttributes;
53 | }
54 |
55 | export interface ScheduleList {
56 | object: 'list';
57 | data: Schedule[];
58 | }
59 |
60 | export interface SheduleEditOptions {
61 | /** Schedule name */
62 | name?: string;
63 | /** Cron minute syntax */
64 | minute?: string;
65 | /** Cron hour syntax */
66 | hour?: string;
67 | /** Cron day of month syntax */
68 | dayOfMonth?: string;
69 | /** Cron month syntax */
70 | month?: string;
71 | /** Cron day of week syntax */
72 | dayOfWeek?: string;
73 | /** Whether the schedule should be activated on creation */
74 | isActive?: boolean;
75 | }
76 |
77 | export interface TaskEditOptions {
78 | /** Action that the schedule should perform (command/power/backup) */
79 | action?: 'command' | 'power' | 'backup';
80 | /** What that action should do. Command or power (start/stop/restart/kill). Backup payload is ignored file list. */
81 | payload?: string;
82 | /** The time offset that the task should run after the schdule is triggered. */
83 | timeOffset?: number;
84 | /** Should the task continue to work on failure. */
85 | continueOnFailure?: boolean;
86 | }
87 |
--------------------------------------------------------------------------------
/src/client/interfaces/Server.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientServer */
2 | export interface ServerSftpDetails {
3 | ip: string;
4 | port: number;
5 | }
6 |
7 | export interface ServerIncludeInput {
8 | egg?: boolean;
9 | subusers?: boolean;
10 | }
11 |
12 | export interface ServerFilterInput {
13 | filter: string;
14 | filterBy: 'uuid' | 'name' | 'external_id' | '*';
15 | }
16 |
17 | export interface ServerLimits {
18 | memory: number;
19 | swap: number;
20 | disk: number;
21 | io: number;
22 | cpu: number;
23 | }
24 |
25 | export interface ServerFeatureLimits {
26 | databases: number;
27 | allocations: number;
28 | backups: number;
29 | }
30 |
31 | export interface ServerEggAttributes {
32 | uuid: string;
33 | name: string;
34 | }
35 |
36 | export interface ServerEgg {
37 | object: string;
38 | attributes: ServerEggAttributes;
39 | }
40 |
41 | export interface ServerSubuserAttributes {
42 | 'uuid': string;
43 | 'username': string;
44 | 'email': string;
45 | 'image': string;
46 | '2fa_enabled': boolean;
47 | 'created_at': string;
48 | 'permissions': string[];
49 | }
50 |
51 | export interface ServerSubuser {
52 | object: string;
53 | attributes: ServerSubuserAttributes;
54 | }
55 |
56 | export interface ServerSubusers {
57 | object: string;
58 | data: ServerSubuser[];
59 | }
60 |
61 | export interface ServerRelationships {
62 | allocations: ServerAllocations;
63 | variables: ServerVariables;
64 | egg?: ServerEgg;
65 | subusers?: ServerSubusers;
66 | }
67 |
68 | export interface ServerAllocations {
69 | object: string;
70 | data: ServerAllocation[];
71 | }
72 |
73 | export interface ServerAllocation {
74 | object: string;
75 | attributes: ServerAllocationAttributes;
76 | }
77 |
78 | export interface ServerAllocationAttributes {
79 | id: number;
80 | ip: string;
81 | ip_alias: string;
82 | port: number;
83 | notes: string;
84 | is_default: boolean;
85 | }
86 |
87 | export interface ServerVariables {
88 | object: string;
89 | data: ServerVariable[];
90 | }
91 |
92 | export interface ServerVariable {
93 | object: string;
94 | attributes: ServerVariableAttributes;
95 | }
96 |
97 | export interface ServerVariableAttributes {
98 | name: string;
99 | description: string;
100 | env_variable: string;
101 | default_value: string;
102 | server_value: string;
103 | is_editable: boolean;
104 | rules: string;
105 | }
106 |
107 | export interface ServerAttributes {
108 | server_owner: boolean;
109 | identifier: string;
110 | internal_id: number;
111 | uuid: string;
112 | name: string;
113 | node: string;
114 | sftp_details: ServerSftpDetails;
115 | description: string;
116 | limits: ServerLimits;
117 | invocation: string;
118 | docker_image: string;
119 | egg_features: unknown;
120 | feature_limits: ServerFeatureLimits;
121 | is_suspended: boolean;
122 | is_installing: boolean;
123 | is_transferring: boolean;
124 | relationships: ServerRelationships;
125 | }
126 |
127 | export interface Server {
128 | object: string;
129 | attributes: ServerAttributes;
130 | }
131 |
132 | export interface Servers {
133 | object: string;
134 | data: Server[];
135 | meta: {
136 | pagination: {
137 | total: number;
138 | count: number;
139 | per_page: number;
140 | current_page: number;
141 | total_pages: number;
142 | };
143 | };
144 | }
145 |
--------------------------------------------------------------------------------
/src/client/interfaces/ServerFile.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientServerFiles */
2 | export interface SeverFileRenameFiles {
3 | from: string;
4 | to: string;
5 | }
6 |
7 | export interface SeverFileRename {
8 | root: string;
9 | files: SeverFileRenameFiles[];
10 | }
11 |
12 | export interface ServerFileCompress {
13 | root: string;
14 | files: string[];
15 | }
16 |
17 | export type ServerFileDelete = ServerFileCompress;
18 |
19 | export interface ServerFileDecompress {
20 | root: string;
21 | file: string;
22 | }
23 |
24 | export interface ServerFileCreateFolder {
25 | root: string;
26 | name: string;
27 | }
28 |
29 | export interface ServerFileAttributes {
30 | name: string;
31 | mode: string;
32 | mode_bits: string;
33 | size: number;
34 | is_file: boolean;
35 | is_symlink: boolean;
36 | mimetype: string;
37 | created_at: string;
38 | modified_at: string;
39 | }
40 |
41 | export interface ServerFile {
42 | object: string;
43 | attributes: ServerFileAttributes;
44 | }
45 |
--------------------------------------------------------------------------------
/src/client/interfaces/ServerResources.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientServerResources */
2 | export interface ServerResource {
3 | memory_bytes: number;
4 | cpu_absolute: number;
5 | disk_bytes: number;
6 | network_rx_bytes: number;
7 | network_tx_bytes: number;
8 | }
9 |
10 | export interface ServerResources {
11 | current_state: string;
12 | is_suspended: boolean;
13 | resources: ServerResource;
14 | }
15 |
--------------------------------------------------------------------------------
/src/client/interfaces/SubUser.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientSubUser */
2 |
3 | export type SubuserPermission =
4 | | 'websocket.connect'
5 | | 'control.console'
6 | | 'control.start'
7 | | 'control.stop'
8 | | 'control.restart'
9 | | 'user.create'
10 | | 'user.read'
11 | | 'user.update'
12 | | 'user.delete'
13 | | 'file.create'
14 | | 'file.read'
15 | | 'file.update'
16 | | 'file.delete'
17 | | 'file.archive'
18 | | 'file.sftp'
19 | | 'allocation.read'
20 | | 'allocation.update'
21 | | 'startup.read'
22 | | 'startup.update'
23 | | 'database.create'
24 | | 'database.read'
25 | | 'database.update'
26 | | 'database.delete'
27 | | 'database.view_password'
28 | | 'schedule.create'
29 | | 'schedule.read'
30 | | 'schedule.update'
31 | | 'schedule.delete';
32 |
33 | export interface SubUserAttributes {
34 | 'uuid': string;
35 | 'username': string;
36 | 'email': string;
37 | 'image': string;
38 | '2fa_enabled': boolean;
39 | 'created_at': string;
40 | 'permissions': SubuserPermission[];
41 | }
42 |
43 | export interface SubUser {
44 | object: 'server_subuser';
45 | attributes: SubUserAttributes;
46 | }
47 |
--------------------------------------------------------------------------------
/src/client/interfaces/User.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientUser */
2 | export interface UserAttributes {
3 | id: number;
4 | admin: boolean;
5 | username: string;
6 | email: string;
7 | first_name: string;
8 | last_name: string;
9 | language: string;
10 | }
11 |
12 | export interface User {
13 | object: 'user';
14 | attributes: UserAttributes;
15 | }
16 |
--------------------------------------------------------------------------------
/src/client/interfaces/WebsocketAuthData.ts:
--------------------------------------------------------------------------------
1 | /** @module ClientWebsocketAuthData */
2 | export interface WebsocketAuthData {
3 | token: string;
4 | socket: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/client/methods/account.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import { ApiKey } from '../interfaces/ApiKey';
3 | import { Permissions } from '../interfaces/Permissions';
4 | import { UserAttributes } from '../interfaces/User';
5 |
6 | export class accountMethods {
7 | constructor(private readonly client: Client) {}
8 | /**
9 | * @returns Permission data
10 | * @remarks Just returns all available permissions. Not that useful!
11 | * @example
12 | * ```ts
13 | * const res = await client.getPermissions() // res = Permissions
14 | * ```
15 | * @example
16 | * ```ts
17 | * client.getPermissions().then((res) => console.log(res)) // res = Permissions
18 | * ```
19 | */
20 | public getAllPermissions = async (): Promise => {
21 | return this.client.request(
22 | 'GET',
23 | null,
24 | 'attributes',
25 | `/api/client/permissions`
26 | );
27 | };
28 | /**
29 | * @returns Account information
30 | * @example
31 | * ```ts
32 | * const res = await client.getAccountInfo() // res = UserAttributes
33 | * ```
34 | * @example
35 | * ```ts
36 | * client.getAccountInfo().then((res) => console.log(res)) // res = UserAttributes
37 | * ```
38 | */
39 | public getAccountInfo = (): Promise => {
40 | return this.client.request(
41 | 'GET',
42 | null,
43 | 'attributes',
44 | `/api/client/account`
45 | );
46 | };
47 | /**
48 | * @returns TOTP QR code image url (otpauth)
49 | * ```ts
50 | * const res = await client.getAccountInfo() // res = string (otpauth)
51 | * ```
52 | * @example
53 | * ```ts
54 | * client.getAccountInfo().then((res) => console.log(res)) // res = string (otpauth)
55 | * ```
56 | */
57 | public getAccount2FADetails = async (): Promise => {
58 | return this.client.request(
59 | 'GET',
60 | null,
61 | 'data.image_url_data',
62 | `/api/client/account/two-factor`
63 | );
64 | };
65 | /**
66 | * @param code - The code from authenticator
67 | * @returns Tokens
68 | * ```ts
69 | * const res = await client.enable2FA('505134') // res = string[] (tokens)
70 | * ```
71 | * @example
72 | * ```ts
73 | * client.enable2FA('505134').then((res) => console.log(res)) // res = string[] (tokens)
74 | * ```
75 | */
76 | public enable2FA = async (code: string): Promise => {
77 | return this.client.request(
78 | 'POST',
79 | {
80 | code: code
81 | },
82 | 'attributes.tokens',
83 | `/api/client/account/two-factor`
84 | );
85 | };
86 | /**
87 | * @param password - The code from authenticator
88 | * @returns If succesful returns Successfully disable 2FA!
89 | * ```ts
90 | * const res = await client.disable2FA('securepassword') // res = Successfully disable 2FA!
91 | * ```
92 | * @example
93 | * ```ts
94 | * client.disable2FA('securepassword').then((res) => console.log(res)) // res = Successfully disable 2FA!
95 | * ```
96 | */
97 | public disable2FA = async (password: string): Promise => {
98 | return this.client.request(
99 | 'DELETE',
100 | {
101 | password: password
102 | },
103 | 'Successfully disable 2FA!',
104 | `/api/client/account/two-factor`
105 | );
106 | };
107 | /**
108 | * @param email - The new email address
109 | * @param password - The password of the user
110 | * @returns If succesful returns Successfully updated email!
111 | * ```ts
112 | * const res = await client.updateEmail('jspteroapi@linux123123.cf', 'verySecurePass') // res = Successfully updated email!
113 | * ```
114 | * @example
115 | * ```ts
116 | * client.updateEmail('jspteroapi@linux123123.cf', 'verySecurePass').then((res) => console.log(res)) // res = Successfully updated email!
117 | * ```
118 | */
119 | public updateEmail = async (
120 | email: string,
121 | password: string
122 | ): Promise => {
123 | return this.client.request(
124 | 'PUT',
125 | {
126 | email: email,
127 | password: password
128 | },
129 | 'Successfully updated email!',
130 | `/api/client/account/email`
131 | );
132 | };
133 | /**
134 | * @param currentPassword - The currect passowrd
135 | * @param password - The new password
136 | * @returns If succesful returns Successfully updated password!
137 | * ```ts
138 | * const res = await client.updatePassword('verySecurePass', 'moreSecurePass') // res = Successfully updated password!
139 | * ```
140 | * @example
141 | * ```ts
142 | * client.updatePassword('verySecurePass', 'moreSecurePass').then((res) => console.log(res)) // res = Successfully updated password!
143 | * ```
144 | */
145 | public updatePassword = async (
146 | currentPassword: string,
147 | password: string
148 | ): Promise => {
149 | return this.client.request(
150 | 'PUT',
151 | {
152 | current_password: currentPassword,
153 | password: password,
154 | password_confirmation: password
155 | },
156 | 'Successfully updated password!',
157 | `/api/client/account/password`
158 | );
159 | };
160 | /**
161 | * @returns Api key array
162 | * @example
163 | * ```ts
164 | * const res = await client.getAllApiKeys() // res = ApiKey[]
165 | * ```
166 | * @example
167 | * ```ts
168 | * client.getAllApiKeys().then((res) => console.log(res)) // res = ApiKey[]
169 | * ```
170 | */
171 | public getAllApiKeys = async (): Promise => {
172 | return this.client.request(
173 | 'GET',
174 | null,
175 | 'data',
176 | `/api/client/account/api-keys`
177 | );
178 | };
179 | /**
180 | * @param description - Api key description
181 | * @param allowedIps - Array of allowed IP addresses (default empty [])
182 | * @returns The new api key information + meta (token)
183 | * ```ts
184 | * const res = await client.createApiKey('TESTING', []) // res = ApiKey + meta (token)
185 | * ```
186 | * @example
187 | * ```ts
188 | * client.createApiKey('TESTING', []).then((res) => console.log(res)) // res = ApiKey + meta (token)
189 | * ```
190 | */
191 | public createApiKey = async (
192 | description: string,
193 | allowedIps: string[] = []
194 | ): Promise => {
195 | return this.client.request(
196 | 'POST',
197 | {
198 | description: description,
199 | allowed_ips: allowedIps
200 | },
201 | '',
202 | `/api/client/account/api-keys`
203 | );
204 | };
205 | /**
206 | * @param apiKeyIden - The api keys identifier code
207 | * @returns If succesful returns Successfully deleted api key!
208 | * ```ts
209 | * const res = await client.deleteApiKey('NWKMYMT2Mrav0Iq2') // res = Successfully deleted api key!
210 | * ```
211 | * @example
212 | * ```ts
213 | * client.deleteApiKey('NWKMYMT2Mrav0Iq2').then((res) => console.log(res)) // res = Successfully deleted api key!
214 | * ```
215 | */
216 | public deleteApiKey = async (apiKeyIden: string): Promise => {
217 | return this.client.request(
218 | 'DELETE',
219 | null,
220 | 'Successfully deleted api key!',
221 | `/api/client/account/api-keys/${apiKeyIden}`
222 | );
223 | };
224 | }
225 |
--------------------------------------------------------------------------------
/src/client/methods/backups.ts:
--------------------------------------------------------------------------------
1 | import { Backup, BackupAttributes, Backups } from 'client/interfaces/Backups';
2 | import { paginate } from '../../modules/Functions';
3 | import { Client } from '../index';
4 |
5 | export class backupMethods {
6 | constructor(private readonly client: Client) {}
7 | /**
8 | * @internal
9 | */
10 | private getBackups = async (serverId: string): Promise => {
11 | return this.client.request(
12 | 'GET',
13 | null,
14 | '',
15 | `/api/client/servers/${serverId}/backups`
16 | );
17 | };
18 | /**
19 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
20 | * @returns An array of backups
21 | * @example
22 | * ```ts
23 | * const res = await client.getAllBackups('7e74354d') // res = Backup[]
24 | * ```
25 | * @example
26 | * ```ts
27 | * client.getAllBackups('7e74354d').then((res) => console.log(res)) // res = Backup[]
28 | * ```
29 | */
30 | public getAllBackups = async (serverId: string): Promise => {
31 | return await paginate(this.getBackups.bind(this, serverId), {});
32 | };
33 | /**
34 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
35 | * @param name - Name of the backup
36 | * @param ignored - Ignored files / folders
37 | * @returns Backup information
38 | * @example
39 | * ```ts
40 | * const res = await client.createBackup('7e74354d') // res = BackupAttributes
41 | * ```
42 | * @example
43 | * ```ts
44 | * client.createBackup('7e74354d', 'RandomBackup').then((res) => console.log(res)) // res = BackupAttributes
45 | * ```
46 | */
47 | public createBackup = async (
48 | serverId: string,
49 | name = '',
50 | ignored: string[] = [],
51 | isLocked = false
52 | ): Promise => {
53 | return this.client.request(
54 | 'POST',
55 | {
56 | name: name,
57 | ignored: ignored.join(' '),
58 | is_locked: isLocked
59 | },
60 | 'attributes',
61 | `/api/client/servers/${serverId}/backups`
62 | );
63 | };
64 | /**
65 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
66 | * @param backupId - ID of the backup to get
67 | * @returns Backup information
68 | * @example
69 | * ```ts
70 | * const res = await client.getBackupInfo('7e74354d', '3a4e4b2a') // res = BackupAttributes
71 | * ```
72 | * @example
73 | * ```ts
74 | * client.getBackupInfo('7e74354d', '3a4e4b2a').then((res) => console.log(res)) // res = BackupAttributes
75 | * ```
76 | */
77 | public getBackupInfo = async (
78 | serverId: string,
79 | backupId: string
80 | ): Promise => {
81 | return this.client.request(
82 | 'GET',
83 | null,
84 | 'attributes',
85 | `/api/client/servers/${serverId}/backups/${backupId}`
86 | );
87 | };
88 | /**
89 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
90 | * @param backupId - ID of the backup to toggle lock of
91 | * @returns Backup information
92 | * @example
93 | * ```ts
94 | * const res = await client.toggleLockBackup('7e74354d', '3a4e4b2a') // res = BackupAttributes
95 | * ```
96 | * @example
97 | * ```ts
98 | * client.toggleLockBackup('7e74354d', '3a4e4b2a').then((res) => console.log(res)) // res = BackupAttributes
99 | * ```
100 | */
101 | public toggleLockBackup = async (
102 | serverId: string,
103 | backupId: string
104 | ): Promise => {
105 | return this.client.request(
106 | 'POST',
107 | null,
108 | 'attributes',
109 | `/api/client/servers/${serverId}/backups/${backupId}/lock`
110 | );
111 | };
112 | /**
113 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
114 | * @param backupId - ID of the backup to restore
115 | * @param truncate - Whether to remove all files before restoring backup
116 | * @returns Sucessfully restored backup
117 | * @example
118 | * ```ts
119 | * const res = await client.restoreBackup('7e74354d', '3a4e4b2a') // res = Sucessfully restored backup
120 | * ```
121 | * @example
122 | * ```ts
123 | * client.restoreBackup('7e74354d', '3a4e4b2a').then((res) => console.log(res)) // res = Sucessfully restored backup
124 | * ```
125 | */
126 | public restoreBackup = async (
127 | serverId: string,
128 | backupId: string,
129 | truncate = false
130 | ): Promise => {
131 | return this.client.request(
132 | 'POST',
133 | { truncate },
134 | 'Sucessfully restored backup',
135 | `/api/client/servers/${serverId}/backups/${backupId}/restore`
136 | );
137 | };
138 | /**
139 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
140 | * @param backupId - ID of the backup to get
141 | * @returns Returns backup download url
142 | * @example
143 | * ```ts
144 | * const res = await client.getBackupDownloadLink('7e74354d', '3a4e4b2a') // res = url (string)
145 | * ```
146 | * @example
147 | * ```ts
148 | * client.getBackupDownloadLink('7e74354d', '3a4e4b2a').then((res) => console.log(res)) // res = url (string)
149 | * ```
150 | */
151 | public getBackupDownloadLink = async (
152 | serverId: string,
153 | backupId: string
154 | ): Promise => {
155 | return this.client.request(
156 | 'GET',
157 | null,
158 | 'attributes.url',
159 | `/api/client/servers/${serverId}/backups/${backupId}/download`
160 | );
161 | };
162 | /**
163 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
164 | * @param backupId - ID of the backup to delete
165 | * @returns Backup information
166 | * @example
167 | * ```ts
168 | * const res = await client.deleteBackup('7e74354d', '3a4e4b2a') // res = Backup successfully deleted!
169 | * ```
170 | * @example
171 | * ```ts
172 | * client.deleteBackup('7e74354d', '3a4e4b2a').then((res) => console.log(res)) // res = Backup successfully deleted!
173 | * ```
174 | */
175 | public deleteBackup = async (
176 | serverId: string,
177 | backupId: string
178 | ): Promise => {
179 | return this.client.request(
180 | 'DELETE',
181 | null,
182 | 'Backup successfully deleted!',
183 | `/api/client/servers/${serverId}/backups/${backupId}`
184 | );
185 | };
186 | }
187 |
--------------------------------------------------------------------------------
/src/client/methods/console.ts:
--------------------------------------------------------------------------------
1 | import { JSPteroAPIError } from 'index';
2 | import { Client } from '../index';
3 | import { WebsocketAuthData } from '../interfaces/WebsocketAuthData';
4 | import { WebsocketClient } from '../Websocket';
5 |
6 | export class consoleMethods {
7 | constructor(
8 | private readonly client: Client,
9 | private readonly errorHandler: (error: JSPteroAPIError) => void
10 | ) {}
11 | /**
12 | * @internal
13 | */
14 | private getWebsocketAuthData = async (
15 | serverId: string
16 | ): Promise => {
17 | return this.client.request(
18 | 'GET',
19 | null,
20 | 'data',
21 | `/api/client/servers/${serverId}/websocket`
22 | );
23 | };
24 | /**
25 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
26 | * @remarks This method is used to connect to server websocket and have automatic authentication. This exposes the websocket client.
27 | * @returns WebsocketClient
28 | * @example
29 | * ```ts
30 | * const res = await client.startConsoleConnection('c2f5a3b6') // res = WebsocketClient
31 | * ```
32 | * @example
33 | * ```ts
34 | * client.startConsoleConnection('c2f5a3b6').then((res) => console.log(res)) // res = WebsocketClient
35 | * ```
36 | */
37 | public startConsoleConnection = async (
38 | serverId: string
39 | ): Promise => {
40 | const auth = await this.getWebsocketAuthData(serverId);
41 | return new WebsocketClient(
42 | this.errorHandler,
43 | auth,
44 | this.getWebsocketAuthData.bind(this, serverId)
45 | );
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/src/client/methods/database.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import { makeOptions } from '../../modules/Functions';
3 | import {
4 | Database,
5 | DatabaseAttributes,
6 | DatabaseIncludeInput
7 | } from '../interfaces/Database';
8 |
9 | export class databaseMethods {
10 | constructor(private readonly client: Client) {}
11 | /**
12 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
13 | * @param options - Include information about relationships
14 | * @returns Returns array of servers databases (Database[])
15 | * @example
16 | * ```ts
17 | * const res = await client.getAllDatabases('c2f5a3b6') // res = Database[]
18 | * ```
19 | * @example
20 | * ```ts
21 | * client.getAllDatabases('c2f5a3b6').then((res) => console.log(res)) // res = Database[]
22 | * ```
23 | */
24 | public getAllDatabases = async (
25 | serverId: string,
26 | options?: DatabaseIncludeInput
27 | ): Promise => {
28 | return this.client.request(
29 | 'GET',
30 | null,
31 | 'data',
32 | `/api/client/servers/${serverId}/databases${makeOptions({
33 | includes: { ...options }
34 | })}`
35 | );
36 | };
37 | /**
38 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
39 | * @param databaseName - Database name
40 | * @param connectionsAllowedFrom - Connections allowed from
41 | * @param options - Include information about relationships
42 | * @returns Returns new database information (DatabaseAttributes)
43 | * @example
44 | * ```ts
45 | * const res = await client.createDatabase('c2f5a3b6', 'Information') // res = DatabaseAttributes
46 | * ```
47 | * @example
48 | * ```ts
49 | * client.createDatabase('c2f5a3b6', 'info').then((res) => console.log(res)) // res = DatabaseAttributes
50 | * ```
51 | */
52 | public createDatabase = async (
53 | serverId: string,
54 | databaseName: string,
55 | connectionsAllowedFrom = '%',
56 | options?: DatabaseIncludeInput
57 | ): Promise => {
58 | return this.client.request(
59 | 'POST',
60 | { database: databaseName, remote: connectionsAllowedFrom },
61 | 'attributes',
62 | `/api/client/servers/${serverId}/databases${makeOptions({
63 | includes: { ...options }
64 | })}`
65 | );
66 | };
67 | /**
68 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
69 | * @param databaseId - Database id
70 | * @returns If successful returns Sucesfully deleted!
71 | * @example
72 | * ```ts
73 | * const res = await client.deleteDatabase('c2f5a3b6', 's5_info') // res = Sucesfully deleted!
74 | * ```
75 | * @example
76 | * ```ts
77 | * client.deleteDatabase('c2f5a3b6', 's3_good').then((res) => console.log(res)) // res = Sucesfully deleted!
78 | * ```
79 | */
80 | public deleteDatabase = (
81 | serverId: string,
82 | databaseId: string
83 | ): Promise => {
84 | return this.client.request(
85 | 'DELETE',
86 | null,
87 | 'Sucesfully deleted!',
88 | `/api/client/servers/${serverId}/databases/${databaseId}`
89 | );
90 | };
91 | /**
92 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
93 | * @param databaseId - Database id
94 | * @returns Returns database information + Relationships(password)
95 | * @example
96 | * ```ts
97 | * const res = await client.rotateDatabasePass('c2f5a3b6', 's5_info') // res = DatabaseAttributesRelationship
98 | * ```
99 | * @example
100 | * ```ts
101 | * client.rotateDatabasePass('c2f5a3b6', 's3_good').then((res) => console.log(res)) // res = DatabaseAttributesRelationship
102 | * ```
103 | */
104 | public rotateDatabasePass = async (
105 | serverId: string,
106 | databaseId: string
107 | ): Promise => {
108 | return this.client.request(
109 | 'POST',
110 | null,
111 | 'attributes',
112 | `/api/client/servers/${serverId}/databases/${databaseId}/rotate-password`
113 | );
114 | };
115 | }
116 |
--------------------------------------------------------------------------------
/src/client/methods/file.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import {
3 | ServerFile,
4 | ServerFileAttributes,
5 | ServerFileCompress,
6 | ServerFileCreateFolder,
7 | ServerFileDecompress,
8 | ServerFileDelete,
9 | SeverFileRename
10 | } from '../interfaces/ServerFile';
11 |
12 | export class fileMethods {
13 | constructor(private readonly client: Client) {}
14 | /**
15 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
16 | * @param dir - Directory to get files from (if not provided gets root server dir) (e. g. dist or dist/classes)
17 | * @returns Array of file objects
18 | * @example
19 | * ```ts
20 | * const res = await client.getAllFiles('c2f5a3b6') // res = ServerFile[]
21 | * ```
22 | * @example
23 | * ```ts
24 | * client.getAllFiles('c2f5a3b6', 'dist').then((res) => console.log(res)) // res = ServerFile[]
25 | * ```
26 | */
27 | public getAllFiles = (serverId: string, dir = ''): Promise => {
28 | return this.client.request(
29 | 'GET',
30 | null,
31 | 'data',
32 | `/api/client/servers/${serverId}/files/list?directory=%2F${dir}`
33 | );
34 | };
35 | /**
36 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
37 | * @param file - File to get the contents of (full name like index.js or dist/index.js)
38 | * @returns Contents of the file (string)
39 | * @example
40 | * ```ts
41 | * const res = await client.getFileContents('c2f5a3b6', 'index.js') // res = content of your file (string)
42 | * ```
43 | * @example
44 | * ```ts
45 | * client.getFileContents('c2f5a3b6', 'dist/index.js').then((res) => console.log(res)) // res = content of your file (string)
46 | * ```
47 | */
48 | public getFileContents = async (
49 | serverId: string,
50 | file: string
51 | ): Promise => {
52 | let filePath = '';
53 | if (file.includes('/')) {
54 | file.split('/').forEach((f) => (filePath += `%2F${f}`));
55 | } else filePath = `%2F${file}`;
56 | return this.client.request(
57 | 'GET',
58 | null,
59 | '',
60 | `/api/client/servers/${serverId}/files/contents?file=${filePath}`,
61 | true
62 | );
63 | };
64 | /**
65 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
66 | * @param file - File to get the contents of (full name like index.js or dist/index.js)
67 | * @param contents - The contents of file you want to write
68 | * @returns If successful returns Successfuly written the file!
69 | * @example
70 | * ```ts
71 | * const res = await client.writeFile('c2f5a3b6', 'HW.txt', 'Hello world!') // res = Successfuly written the file!
72 | * ```
73 | * @example
74 | * ```ts
75 | * client.writeFile('c2f5a3b6', 'dist/HW.txt', 'Hello world!').then((res) => console.log(res)) // res = Successfuly written the file!
76 | * ```
77 | */
78 | public writeFile = async (
79 | serverId: string,
80 | file: string,
81 | contents: string
82 | ): Promise => {
83 | return this.client.request(
84 | 'POST',
85 | contents,
86 | 'Successfuly written the file!',
87 | `/api/client/servers/${serverId}/files/write?file=${encodeURIComponent(
88 | file
89 | )}`
90 | );
91 | };
92 | /**
93 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
94 | * @param data - An object composed of root of the file and array of objects for files to rename
95 | * @returns If successful returns Successfuly renamed!
96 | * @example
97 | * ```ts
98 | * const res = await client.renameFile('c2f5a3b6', { root: '/', files: [{ from: 'LICENSE', to: 'LIC' }] }) // res = Successfuly renamed!
99 | * ```
100 | * @example
101 | * ```ts
102 | * client.renameFile('c2f5a3b6', { root: '/dist', files: [{ from: 'LICENSE', to: 'LIC' }] }).then((res) => console.log(res)) // res = Successfuly renamed!
103 | * ```
104 | */
105 | public renameFile = async (
106 | serverId: string,
107 | data: SeverFileRename
108 | ): Promise => {
109 | return this.client.request(
110 | 'PUT',
111 | data,
112 | 'Successfuly renamed!',
113 | `/api/client/servers/${serverId}/files/rename`
114 | );
115 | };
116 | /**
117 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
118 | * @param location - Location of file to copy (e. g. /LICENSE) (It will create a /LICENSE copy)
119 | * @returns If successful returns Successfuly copied!
120 | * @example
121 | * ```ts
122 | * const res = await client.copyFile('c2f5a3b6', '/LICENSE') // res = Successfuly copied!
123 | * ```
124 | * @example
125 | * ```ts
126 | * client.copyFile('c2f5a3b6', '/dist/LICENSE').then((res) => console.log(res)) // res = Successfuly copied!
127 | * ```
128 | */
129 | public copyFile = async (
130 | serverId: string,
131 | location: string
132 | ): Promise => {
133 | return this.client.request(
134 | 'POST',
135 | { location: location },
136 | 'Successfuly copied!',
137 | `/api/client/servers/${serverId}/files/copy`
138 | );
139 | };
140 | /**
141 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
142 | * @param file - File to get the contents of (full name like index.js or dist/index.js)
143 | * @returns Returns file download url
144 | * @example
145 | * ```ts
146 | * const res = await client.getFileDownloadLink('c2f5a3b6', 'index.js') // res = url (string)
147 | * ```
148 | * @example
149 | * ```ts
150 | * client.getServerResources('c2f5a3b6', 'dist/index.js').then((res) => console.log(res)) // res = url (string)
151 | * ```
152 | */
153 | public getFileDownloadLink = async (
154 | serverId: string,
155 | file: string
156 | ): Promise => {
157 | let filePath = '';
158 | if (file.includes('/')) {
159 | file.split('/').forEach((f) => (filePath += `%2F${f}`));
160 | } else filePath = `%2F${file}`;
161 | return this.client.request(
162 | 'GET',
163 | null,
164 | 'attributes.url',
165 | `/api/client/servers/${serverId}/files/download?file=${filePath}`
166 | );
167 | };
168 | /**
169 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
170 | * @param data - An object composed of root of the file and array of objects for files to rename
171 | * @returns Returns a archive file information
172 | * @example
173 | * ```ts
174 | * const res = await client.compressFile('c2f5a3b6', { root: '/', files: ['README.md', 'LICENSE'] }) // res = ServerFileAttributes
175 | * ```
176 | * @example
177 | * ```ts
178 | * client.compressFile('c2f5a3b6', { root: '/', files: ['README.md', 'LICENSE'] }).then((res) => console.log(res)) // res = ServerFileAttributes
179 | * ```
180 | */
181 | public compressFile = async (
182 | serverId: string,
183 | data: ServerFileCompress
184 | ): Promise => {
185 | return this.client.request(
186 | 'POST',
187 | data,
188 | 'attributes',
189 | `/api/client/servers/${serverId}/files/compress`
190 | );
191 | };
192 | /**
193 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
194 | * @param data - An object composed of root of the file and file to remove
195 | * @returns If successful returns Successfuly decompressed!
196 | * @example
197 | * ```ts
198 | * const res = await client.decompressFile('c2f5a3b6', { root: '/', file: 'archive.tar.gz' }) // res = Successfuly decompressed!
199 | * ```
200 | * @example
201 | * ```ts
202 | * client.decompressFile('c2f5a3b6', { root: '/', file: 'archive.tar.gz' }).then((res) => console.log(res)) // res = Successfuly decompressed!
203 | * ```
204 | */
205 | public decompressFile = async (
206 | serverId: string,
207 | data: ServerFileDecompress
208 | ): Promise => {
209 | return this.client.request(
210 | 'POST',
211 | data,
212 | 'Successfuly decompressed!',
213 | `/api/client/servers/${serverId}/files/decompress`
214 | );
215 | };
216 | /**
217 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
218 | * @param data - An object composed of root of the file and array of string (file names) for files to rename
219 | * @returns If successful returns Successfuly deleted!
220 | * @example
221 | * ```ts
222 | * const res = await client.deleteFile('c2f5a3b6', { root: '/', files: ['README.md'] }) // res = Successfuly deleted!
223 | * ```
224 | * @example
225 | * ```ts
226 | * client.deleteFile('c2f5a3b6', { root: '/', files: ['LICENSE', 'README.md'] }).then((res) => console.log(res)) // res = Successfuly deleted!
227 | * ```
228 | */
229 | public deleteFile = async (
230 | serverId: string,
231 | data: ServerFileDelete
232 | ): Promise => {
233 | return this.client.request(
234 | 'POST',
235 | data,
236 | 'Successfuly deleted!',
237 | `/api/client/servers/${serverId}/files/delete`
238 | );
239 | };
240 | /**
241 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
242 | * @param data - An object composed of root of the file and file to remove
243 | * @returns If successful returns Successfuly created!
244 | * @example
245 | * ```ts
246 | * const res = await client.createFolder('c2f5a3b6', { root: '/', name: 'world' }) // res = Successfuly created!
247 | * ```
248 | * @example
249 | * ```ts
250 | * client.createFolder('c2f5a3b6', { root: '/', name: 'world' }).then((res) => console.log(res)) // res = Successfuly created!
251 | * ```
252 | */
253 | public createFolder = async (
254 | serverId: string,
255 | data: ServerFileCreateFolder
256 | ): Promise => {
257 | return this.client.request(
258 | 'POST',
259 | data,
260 | 'Successfuly created!',
261 | `/api/client/servers/${serverId}/files/create-folder`
262 | );
263 | };
264 | /**
265 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
266 | * @returns If successful returns upload url
267 | * @example
268 | * ```ts
269 | * const res = await client.getFileUploadLink('c2f5a3b6') // res = url (string)
270 | * ```
271 | * @example
272 | * ```ts
273 | * client.getFileUploadLink('c2f5a3b6').then((res) => console.log(res)) // res = url (string)
274 | * ```
275 | */
276 | public getFileUploadLink = async (serverId: string): Promise => {
277 | return this.client.request(
278 | 'GET',
279 | null,
280 | 'attributes.url',
281 | `/api/client/servers/${serverId}/files/upload`
282 | );
283 | };
284 | }
285 |
--------------------------------------------------------------------------------
/src/client/methods/network.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import { Allocation } from '../interfaces/Allocation';
3 |
4 | export class networkMethods {
5 | constructor(private readonly client: Client) {}
6 | /**
7 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
8 | * @returns Array of allocations
9 | * @example
10 | * ```ts
11 | * const res = await client.getAllAlocations('c2f5a3b6') // res = Allocation[]
12 | * ```
13 | * @example
14 | * ```ts
15 | * client.getAllAlocations('c2f5a3b6').then((res) => console.log(res)) // res = Allocation[]
16 | * ```
17 | */
18 | public getAllAlocations = (serverId: string): Promise => {
19 | return this.client.request(
20 | 'GET',
21 | null,
22 | 'data',
23 | `/api/client/servers/${serverId}/network/allocations`
24 | );
25 | };
26 | /**
27 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
28 | * @remarks This method is only available if auto-assign is enabled
29 | * @example
30 | * ```ts
31 | * const res = await client.assignAllocation('c2f5a3b6') // res = Allocation
32 | * ```
33 | * @example
34 | * ```ts
35 | * client.assignAllocation('c2f5a3b6').then((res) => console.log(res)) // res = Allocation
36 | * ```
37 | */
38 | public assignAllocation = (serverId: string): Promise => {
39 | return this.client.request(
40 | 'POST',
41 | null,
42 | 'attributes',
43 | `/api/client/servers/${serverId}/network/allocations`
44 | );
45 | };
46 | /**
47 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
48 | * @param allocationId - ID of the allocation to set the note for
49 | * @param note - The note you want to set
50 | * @example
51 | * ```ts
52 | * const res = await client.setAllocationNote('c2f5a3b6', 1, "Port for RDP") // res = Allocation
53 | * ```
54 | * @example
55 | * ```ts
56 | * client.setAllocationNote('c2f5a3b6', 1, "Port for RDP").then((res) => console.log(res)) // res = Allocation
57 | * ```
58 | */
59 | public setAllocationNote = (
60 | serverId: string,
61 | allocationId: number,
62 | note: string
63 | ): Promise => {
64 | return this.client.request(
65 | 'POST',
66 | { notes: note },
67 | 'attributes',
68 | `/api/client/servers/${serverId}/network/allocations/${allocationId}`
69 | );
70 | };
71 | /**
72 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
73 | * @param allocationId - ID of the allocation to make primary
74 | * @example
75 | * ```ts
76 | * const res = await client.setAllocationPrimary('c2f5a3b6', 1) // res = Allocation
77 | * ```
78 | * @example
79 | * ```ts
80 | * client.setAllocationPrimary('c2f5a3b6', 1).then((res) => console.log(res)) // res = Allocation
81 | * ```
82 | */
83 | public setAllocationPrimary = (
84 | serverId: string,
85 | allocationId: number
86 | ): Promise => {
87 | return this.client.request(
88 | 'POST',
89 | null,
90 | 'attributes',
91 | `/api/client/servers/${serverId}/network/allocations/${allocationId}/primary`
92 | );
93 | };
94 | /**
95 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
96 | * @param allocationId - ID of the allocation to delete
97 | * @remarks This method is only available if allocation is not primary
98 | * @example
99 | * ```ts
100 | * const res = await client.deleteAllocation('c2f5a3b6', 1) // res = Sucessfully deleted Allocation!
101 | * ```
102 | * @example
103 | * ```ts
104 | * client.deleteAllocation('c2f5a3b6', 1).then((res) => console.log(res)) // res = Sucessfully deleted Allocation!
105 | * ```
106 | */
107 | public deleteAllocation = (
108 | serverId: string,
109 | allocationId: number
110 | ): Promise => {
111 | return this.client.request(
112 | 'DELETE',
113 | null,
114 | 'Sucessfully deleted Allocation!',
115 | `/api/client/servers/${serverId}/network/allocations/${allocationId}`
116 | );
117 | };
118 | }
119 |
--------------------------------------------------------------------------------
/src/client/methods/schedule.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import {
3 | Schedule,
4 | ScheduleAttributes,
5 | ScheduleTaskAttributes,
6 | SheduleEditOptions,
7 | TaskEditOptions
8 | } from '../interfaces/Schedule';
9 |
10 | export class scheduleMethods {
11 | constructor(private readonly client: Client) {}
12 | /**
13 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
14 | * @returns An Array of servers schedules
15 | * @example
16 | * ```ts
17 | * const res = await client.getAllSchedules() // res = Schedule[]
18 | * ```
19 | * @example
20 | * ```ts
21 | * client.getAllSchedules().then((res) => console.log(res)) // res = Schedule[]
22 | * ```
23 | */
24 | public getAllSchedules = async (serverId: string): Promise => {
25 | return this.client.request(
26 | 'GET',
27 | null,
28 | 'data',
29 | `/api/client/servers/${serverId}/schedules`
30 | );
31 | };
32 | /**
33 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
34 | * @param name - Name of the schedule
35 | * @param minute - Cron minute syntax
36 | * @param hour - Cron hour syntax
37 | * @param dayOfMonth - Cron day of month syntax
38 | * @param month - Cron month syntax
39 | * @param dayOfWeek - Cron day of week syntax
40 | * @param isActive - Whether the schedule should be activated on creation (default true)
41 | * @param onlyWhenOnline - Whether the schedule should only run when server is on (default true)
42 | * @returns The schedule information
43 | * @example
44 | * ```ts
45 | * const res = await client.createSchedule('TESTING', '*', '*', '*', '*') // res = ScheduleAttributes
46 | * ```
47 | * @example
48 | * ```ts
49 | * client.createSchedule('TESTING', '*', '*', '*', '*').then((res) => console.log(res)) // res = ScheduleAttributes
50 | * ```
51 | */
52 | public createSchedule = async (
53 | serverId: string,
54 | name: string,
55 | minute: string,
56 | hour: string,
57 | dayOfMonth: string,
58 | month: string,
59 | dayOfWeek: string,
60 | isActive = true,
61 | onlyWhenOnline = true
62 | ): Promise => {
63 | return this.client.request(
64 | 'POST',
65 | {
66 | name: name,
67 | minute: minute,
68 | hour: hour,
69 | day_of_month: dayOfMonth,
70 | month: month,
71 | day_of_week: dayOfWeek,
72 | is_active: isActive,
73 | only_when_online: onlyWhenOnline
74 | },
75 | 'attributes',
76 | `/api/client/servers/${serverId}/schedules`
77 | );
78 | };
79 | /**
80 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
81 | * @param scheduleId - Id of the schedule to get info
82 | * @returns Schedule information
83 | * @example
84 | * ```ts
85 | * const res = await client.getScheduleInfo('7e74354d', 7) // res = ScheduleAttributes
86 | * ```
87 | * @example
88 | * ```ts
89 | * client.getScheduleInfo('7e74354d', 8).then((res) => console.log(res)) // res = ScheduleAttributes
90 | * ```
91 | */
92 | public getScheduleInfo = async (
93 | serverId: string,
94 | scheduleId: number
95 | ): Promise => {
96 | return this.client.request(
97 | 'GET',
98 | null,
99 | 'attributes',
100 | `/api/client/servers/${serverId}/schedules/${scheduleId}`
101 | );
102 | };
103 | /**
104 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
105 | * @param scheduleId - Id of the schedule to edit
106 | * @param options - Edit schedule options
107 | * @returns The schedule information
108 | * @example
109 | * ```ts
110 | * const res = await client.editSchedule('7e74354d', 5, { name: 'EditedName' }) // res = ScheduleAttributes
111 | * ```
112 | * @example
113 | * ```ts
114 | * client.editSchedule('7e74354d', 5, { name: 'EditedName' }).then((res) => console.log(res)) // res = ScheduleAttributes
115 | * ```
116 | */
117 | public editSchedule = async (
118 | serverId: string,
119 | scheduleId: number,
120 | options: SheduleEditOptions
121 | ): Promise => {
122 | const schedule = await this.getScheduleInfo(serverId, scheduleId);
123 | return this.client.request(
124 | 'POST',
125 | {
126 | name: options.name ?? schedule.name,
127 | minute: options.minute ?? schedule.cron.minute,
128 | hour: options.hour ?? schedule.cron.hour,
129 | day_of_month: options.dayOfMonth ?? schedule.cron.day_of_month,
130 | month: options.month ?? schedule.cron.month,
131 | day_of_week: options.dayOfWeek ?? schedule.cron.day_of_week,
132 | is_active: options.isActive ?? schedule.is_active
133 | },
134 | 'attributes',
135 | `/api/client/servers/${serverId}/schedules/${scheduleId}`
136 | );
137 | };
138 | /**
139 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
140 | * @param scheduleId - Id of the schedule to delete
141 | * @returns Successfuly deleted schedule!
142 | * @example
143 | * ```ts
144 | * const res = await client.deleteSchedule('7e74354d', 5) // res = Successfuly deleted schedule!
145 | * ```
146 | * @example
147 | * ```ts
148 | * client.deleteSchedule('7e74354d', 5).then((res) => console.log(res)) // res = Successfuly deleted schedule!
149 | * ```
150 | */
151 | public deleteSchedule = async (
152 | serverId: string,
153 | scheduleId: number
154 | ): Promise => {
155 | return this.client.request(
156 | 'DELETE',
157 | null,
158 | 'Successfuly deleted schedule!',
159 | `/api/client/servers/${serverId}/schedules/${scheduleId}`
160 | );
161 | };
162 | /**
163 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
164 | * @param scheduleId - Id of the schedule to create task for
165 | * @param action - Action that the schedule should perform (command/power/backup)
166 | * @param payload - What that action should do. Command or power (start/stop/restart/kill). Backup payload is ignored file list.
167 | * @param timeOffset - The time offset that the task should run after the schdule is triggered. (default 0)
168 | * @param continueOnFailure - Should the task continue to work on failure. (default false)
169 | * @returns The task information
170 | * @example
171 | * ```ts
172 | * const res = await client.createTask('7e74354d', 5, 'power', 'start') // res = ScheduleTaskAttributes
173 | * ```
174 | * @example
175 | * ```ts
176 | * client.createTask('7e74354d', 5, 'power', 'start').then((res) => console.log(res)) // res = ScheduleTaskAttributes
177 | * ```
178 | */
179 | public createTask = async (
180 | serverId: string,
181 | scheduleId: number,
182 | action: 'command' | 'power' | 'backup',
183 | payload: string,
184 | timeOffset = 0,
185 | continueOnFailure = false
186 | ): Promise => {
187 | return this.client.request(
188 | 'POST',
189 | {
190 | action: action,
191 | time_offset: timeOffset,
192 | payload: payload,
193 | continue_on_failure: continueOnFailure
194 | },
195 | 'attributes',
196 | `/api/client/servers/${serverId}/schedules/${scheduleId}/tasks`
197 | );
198 | };
199 | /**
200 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
201 | * @param scheduleId - ID of the schedule to edit task for
202 | * @param taskId - ID of the task to edit
203 | * @returns The task information
204 | * @example
205 | * ```ts
206 | * const res = await client.editTask('7e74354d', 5, 1, { payload: 'restart' }) // res = ScheduleTaskAttributes
207 | * ```
208 | * @example
209 | * ```ts
210 | * client.editTask('7e74354d', 5, 1, { payload: 'restart' }).then((res) => console.log(res)) // res = ScheduleTaskAttributes
211 | * ```
212 | */
213 | public editTask = async (
214 | serverId: string,
215 | scheduleId: number,
216 | taskId: number,
217 | options: TaskEditOptions
218 | ): Promise => {
219 | const schedule = await this.getScheduleInfo(serverId, scheduleId);
220 | const task = schedule.relationships.tasks.data.find(
221 | ({ attributes: { id } }) => id === taskId
222 | )?.attributes;
223 | if (!task) throw new Error('Task could not be found!');
224 | return this.client.request(
225 | 'POST',
226 | {
227 | action: options.action ?? task.action,
228 | time_offset: options.timeOffset ?? task.time_offset,
229 | payload: options.payload ?? task.payload,
230 | continue_on_failure:
231 | options.continueOnFailure ?? task.continue_on_failure
232 | },
233 | 'attributes',
234 | `/api/client/servers/${serverId}/schedules/${scheduleId}/tasks/${taskId}`
235 | );
236 | };
237 | /**
238 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
239 | * @param scheduleId - ID of the schedule
240 | * @param taskId - ID of the task to delete
241 | * @returns Successfuly deleted schedule!
242 | * @example
243 | * ```ts
244 | * const res = await client.deleteTask('7e74354d', 5) // res = Successfuly deleted schedule!
245 | * ```
246 | * @example
247 | * ```ts
248 | * client.deleteTask('7e74354d', 5).then((res) => console.log(res)) // res = Successfuly deleted schedule!
249 | * ```
250 | */
251 | public deleteTask = async (
252 | serverId: string,
253 | scheduleId: number,
254 | taskId: number
255 | ): Promise => {
256 | return this.client.request(
257 | 'DELETE',
258 | null,
259 | 'Successfuly deleted task!',
260 | `/api/client/servers/${serverId}/schedules/${scheduleId}/tasks/${taskId}`
261 | );
262 | };
263 | }
264 |
--------------------------------------------------------------------------------
/src/client/methods/server.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 | import { makeOptions, MakeOpts, paginate } from '../../modules/Functions';
3 | import {
4 | Server,
5 | ServerAttributes,
6 | ServerFilterInput,
7 | ServerIncludeInput,
8 | Servers
9 | } from '../interfaces/Server';
10 | import { ServerResources } from '../interfaces/ServerResources';
11 |
12 | export class serverMethods {
13 | constructor(private readonly client: Client) {}
14 | /**
15 | * @internal
16 | */
17 | private getServers = async (options: MakeOpts): Promise => {
18 | return this.client.request(
19 | 'GET',
20 | null,
21 | '',
22 | `/api/client${makeOptions(options)}`
23 | );
24 | };
25 | /**
26 | * @param options - Include information about server relationships
27 | * @param filter - Filter servers by specified field and value
28 | * @returns An Array of servers
29 | * @example
30 | * ```ts
31 | * const res = await client.getAllServers() // res = Server[]
32 | * ```
33 | * @example
34 | * ```ts
35 | * client.getAllServers().then((res) => console.log(res)) // res = Server[]
36 | * ```
37 | */
38 | public getAllServers = async (
39 | options?: ServerIncludeInput,
40 | filter?: ServerFilterInput,
41 | admin = false
42 | ): Promise => {
43 | return await paginate(this.getServers.bind(this), {
44 | includes: { ...options },
45 | admin: admin,
46 | filter: filter
47 | });
48 | };
49 | /**
50 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
51 | * @param options - Include information about server relationships
52 | * @returns Server information
53 | * @example
54 | * ```ts
55 | * const res = await client.getServerInfo('c2f5a3b6') // res = ServerAttributes
56 | * ```
57 | * @example
58 | * ```ts
59 | * client.getServerInfo('c2f5a3b6').then((res) => console.log(res)) // res = ServerAttributes
60 | * ```
61 | */
62 | public getServerInfo = async (
63 | serverId: string,
64 | options?: ServerIncludeInput
65 | ): Promise => {
66 | return this.client.request(
67 | 'GET',
68 | null,
69 | 'attributes',
70 | `/api/client/servers/${serverId}${makeOptions({
71 | includes: { ...options }
72 | })}`
73 | );
74 | };
75 | /**
76 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
77 | * @returns Server resource usage object
78 | * @example
79 | * ```ts
80 | * const res = await client.getServerResources('c2f5a3b6') // res = ServerResources
81 | * ```
82 | * @example
83 | * ```ts
84 | * client.getServerResources('c2f5a3b6').then((res) => console.log(res)) // res = ServerResources
85 | * ```
86 | */
87 | public getServerResources = async (
88 | serverId: string
89 | ): Promise => {
90 | return this.client.request(
91 | 'GET',
92 | null,
93 | 'attributes',
94 | `/api/client/servers/${serverId}/resources`
95 | );
96 | };
97 | /**
98 | * @param serverId - ID of the server to send a command to
99 | * @param command - Command to send
100 | * @returns If successful returns Successfuly sent the command!
101 | * @example
102 | * ```ts
103 | * const res = await client.sendCommand('c2f5a3b6', 'give Linux123123 star') // res = Successfuly sent the command!
104 | * ```
105 | * @example
106 | * ```ts
107 | * client.sendCommand('c2f5a3b6', 'give Linux123123 star').then((res) => console.log(res)) // res = Successfuly sent the command!
108 | * ```
109 | */
110 | public sendCommand = async (
111 | serverId: string,
112 | command: string
113 | ): Promise => {
114 | return this.client.request(
115 | 'POST',
116 | { command: command },
117 | 'Successfuly sent the command!',
118 | `/api/client/servers/${serverId}/command`
119 | );
120 | };
121 | /**
122 | * @param serverId - ID of the server to send a command to
123 | * @param action - start / stop / restart / kill
124 | * @returns If successful returns Successfuly set power state!
125 | * @example
126 | * ```ts
127 | * const res = await client.setPowerState('c2f5a3b6', 'start') // res = Successfuly set power state!
128 | * ```
129 | * @example
130 | * ```ts
131 | * client.setPowerState('c2f5a3b6', 'kill).then((res) => console.log(res)) // res = Successfuly set power state!
132 | * ```
133 | */
134 | public setPowerState = async (
135 | serverId: string,
136 | action: 'start' | 'stop' | 'restart' | 'kill'
137 | ): Promise => {
138 | return this.client.request(
139 | 'POST',
140 | { signal: action },
141 | 'Successfuly set power state!',
142 | `/api/client/servers/${serverId}/power`
143 | );
144 | };
145 | }
146 |
--------------------------------------------------------------------------------
/src/client/methods/settings.ts:
--------------------------------------------------------------------------------
1 | import { Client } from '../index';
2 |
3 | export class settingsMethods {
4 | constructor(private readonly client: Client) {}
5 | /**
6 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
7 | * @param name - New name for the server
8 | * @returns Successfuly set new server name!
9 | * @example
10 | * ```ts
11 | * const res = await client.renameServer('c2f5a3b6', 'Best Server') // res = Successfuly set new server name!
12 | * ```
13 | * @example
14 | * ```ts
15 | * client.renameServer('c2f5a3b6', 'Best Server').then((res) => console.log(res)) // res = Successfuly set new server name!
16 | * ```
17 | */
18 | public renameServer = async (
19 | serverId: string,
20 | name: string
21 | ): Promise => {
22 | return await this.client.request(
23 | 'POST',
24 | { name },
25 | 'Successfuly set new server name!',
26 | `/api/client/servers/${serverId}/settings/rename`
27 | );
28 | };
29 | /**
30 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
31 | * @returns Successfuly started reinstalling!
32 | * @example
33 | * ```ts
34 | * const res = await client.reinstallServer('c2f5a3b6') // res = Successfuly started reinstalling!
35 | * ```
36 | * @example
37 | * ```ts
38 | * client.reinstallServer('c2f5a3b6').then((res) => console.log(res)) // res = Successfuly started reinstalling!
39 | * ```
40 | */
41 | public reinstallServer = async (serverId: string): Promise => {
42 | return await this.client.request(
43 | 'POST',
44 | null,
45 | 'Successfuly started reinstalling!',
46 | `/api/client/servers/${serverId}/settings/reinstall`
47 | );
48 | };
49 | }
50 |
--------------------------------------------------------------------------------
/src/client/methods/subUser.ts:
--------------------------------------------------------------------------------
1 | import {
2 | SubUser,
3 | SubUserAttributes,
4 | SubuserPermission
5 | } from 'client/interfaces/SubUser';
6 | import { Client } from '../index';
7 |
8 | export class subUserMethods {
9 | constructor(private readonly client: Client) {}
10 | /**
11 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
12 | * @returns SubUser[]
13 | * @example
14 | * ```ts
15 | * const res = await client.getAllSubUsers('c2f5a3b6') // res = SubUser[]
16 | * ```
17 | * @example
18 | * ```ts
19 | * client.getAllSubUsers('c2f5a3b6').then((res) => console.log(res)) // res = SubUser[]
20 | * ```
21 | */
22 | public getAllSubUsers = async (serverId: string): Promise => {
23 | return this.client.request(
24 | 'GET',
25 | null,
26 | 'data',
27 | `/api/client/servers/${serverId}/users`
28 | );
29 | };
30 | /**
31 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
32 | * @param subUserId - UUID of the subuser to get
33 | * @returns SubUserAttributes
34 | * @example
35 | * ```ts
36 | * const res = await client.getSubUserInfo('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4') // res = SubUserAttributes
37 | * ```
38 | * @example
39 | * ```ts
40 | * client.getSubUserInfo('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4').then((res) => console.log(res)) // res = SubUserAttributes
41 | * ```
42 | */
43 | public getSubUserInfo = async (
44 | serverId: string,
45 | subUserId: string
46 | ): Promise => {
47 | return this.client.request(
48 | 'GET',
49 | null,
50 | 'attributes',
51 | `/api/client/servers/${serverId}/users/${subUserId}`
52 | );
53 | };
54 | /**
55 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
56 | * @param email - Email of the subuser
57 | * @param permission - Permission of the subuser
58 | * @returns SubUserAttributes
59 | * @example
60 | * ```ts
61 | * const res = await client.createSubUser('c2f5a3b6', 'api@gmail.com', ['control.console']) // res = SubUserAttributes
62 | * ```
63 | * @example
64 | * ```ts
65 | * client.createSubUser('c2f5a3b6', 'api@gmail.com', ['control.console']).then((res) => console.log(res)) // res = SubUserAttributes
66 | * ```
67 | */
68 | public createSubUser = async (
69 | serverId: string,
70 | email: string,
71 | permissions: SubuserPermission[]
72 | ): Promise => {
73 | return this.client.request(
74 | 'POST',
75 | { email, permissions },
76 | 'attributes',
77 | `/api/client/servers/${serverId}/users`
78 | );
79 | };
80 | /**
81 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
82 | * @param subUserId - UUID of the subuser to get
83 | * @param permission - Permission of the subuser
84 | * @returns SubUserAttributes
85 | * @example
86 | * ```ts
87 | * const res = await client.updateSubUserPermissions('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4', ['control.console']) // res = SubUserAttributes
88 | * ```
89 | * @example
90 | * ```ts
91 | * client.updateSubUserPermissions('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4', ['control.console']).then((res) => console.log(res)) // res = SubUserAttributes
92 | * ```
93 | */
94 | public updateSubUserPermissions = async (
95 | serverId: string,
96 | subUserId: string,
97 | permissions: SubuserPermission[]
98 | ): Promise => {
99 | return this.client.request(
100 | 'POST',
101 | { permissions },
102 | 'attributes',
103 | `/api/client/servers/${serverId}/users/${subUserId}`
104 | );
105 | };
106 | /**
107 | * @param serverId - ID of the server to get (In the settings tab of server/in link)
108 | * @param subUserId - UUID of the subuser to get
109 | * @returns If successful returns Successfuly deleted SubUser!
110 | * @example
111 | * ```ts
112 | * const res = await client.deleteSubUser('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4') // res = Successfuly deleted SubUser!
113 | * ```
114 | * @example
115 | * ```ts
116 | * client.deleteSubUser('c2f5a3b6', '60a7aec3-e17d-4aa9-abb3-56d944d204b4').then((res) => console.log(res)) // res = Successfuly deleted SubUser!
117 | * ```
118 | */
119 | public deleteSubUser = async (
120 | serverId: string,
121 | subUserId: string
122 | ): Promise => {
123 | return this.client.request(
124 | 'DELETE',
125 | null,
126 | 'Successfuly deleted SubUser!',
127 | `/api/client/servers/${serverId}/users/${subUserId}`
128 | );
129 | };
130 | }
131 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * The main entrypoint for the API
3 | * @module JSPteroAPI
4 | * @category Main
5 | */
6 | import { Application } from './application/index';
7 | import { Client } from './client/index';
8 | import { JSPteroAPIError } from './modules/Error';
9 | export { Application, Client, JSPteroAPIError };
10 | export default {
11 | Application,
12 | Client
13 | };
14 |
--------------------------------------------------------------------------------
/src/modules/Error.ts:
--------------------------------------------------------------------------------
1 | /** @module JSPteroAPIError */
2 |
3 | import { Response } from 'undici';
4 |
5 | export interface pterodactylError {
6 | errors?: [
7 | {
8 | code: string;
9 | status: string;
10 | detail: string;
11 | }
12 | ];
13 | }
14 |
15 | export class JSPteroAPIError extends Error {
16 | constructor(
17 | rawData: Response,
18 | JSONData: pterodactylError,
19 | data: Record | string | null,
20 | requestType: 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT'
21 | ) {
22 | super();
23 | this.HTML_URL = rawData.url;
24 | this.HTML_STATUS = rawData.status;
25 | this.HTML_STATUS_TEXT = rawData.statusText;
26 | this.REQUEST_TYPE = requestType;
27 | if (data) this.REQUEST_BODY = data;
28 | const errors: string[] = [];
29 | if (JSONData.errors)
30 | JSONData.errors.forEach((element) => {
31 | errors.push(element.detail);
32 | });
33 | this.ERRORS = errors;
34 | }
35 | public HTML_URL: string;
36 | public HTML_STATUS: number;
37 | public HTML_STATUS_TEXT: string;
38 | public REQUEST_TYPE: 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT';
39 | public REQUEST_BODY!: Record | string;
40 | public ERRORS: string[];
41 | }
42 |
--------------------------------------------------------------------------------
/src/modules/Functions.ts:
--------------------------------------------------------------------------------
1 | export interface MakeIncl {
2 | [key: string]: boolean;
3 | }
4 |
5 | export interface MakeFilter {
6 | filter: string;
7 | filterBy: string;
8 | }
9 |
10 | export interface MakeOpts {
11 | includes?: MakeIncl;
12 | filter?: MakeFilter;
13 | admin?: boolean;
14 | page?: number;
15 | }
16 |
17 | export const makeOptions = (options: MakeOpts): string => {
18 | const query = new URLSearchParams();
19 | if (options.page) {
20 | query.append('page', options.page.toString());
21 | // Also append per page just in case it's not set
22 | // I make 75 the default becase it's a reasonable default
23 | query.append('per_page', '75');
24 | }
25 | if (options.includes) {
26 | let includes = '';
27 | const optionsArray = Object.entries(options.includes);
28 | if (optionsArray.some(([, value]) => value === true)) {
29 | optionsArray.forEach(([key, value]) => {
30 | if (value) includes += `${key},`;
31 | });
32 | }
33 | if (includes) {
34 | query.append('include', includes.slice(0, -1));
35 | }
36 | }
37 | if (options.filter)
38 | query.append(`filter[${options.filter.filterBy}]`, options.filter.filter);
39 |
40 | if (options.admin) query.append('type', 'admin-all');
41 | const queryString = query.toString();
42 | return queryString ? `?${queryString}` : '';
43 | };
44 |
45 | export const paginate = async (
46 | request: (options: MakeOpts) => Promise<{
47 | data: T[];
48 | meta: {
49 | pagination: {
50 | total_pages: number;
51 | };
52 | };
53 | }>,
54 | options: MakeOpts
55 | ): Promise => {
56 | const page1 = await request({ ...options, page: 1 });
57 | let data = page1.data;
58 | if (page1.meta.pagination.total_pages > 1) {
59 | for (let i = 2; i <= page1.meta.pagination.total_pages; i++) {
60 | const page = await request({
61 | ...options,
62 | page: i
63 | });
64 | data = data.concat(page.data);
65 | }
66 | }
67 | return data;
68 | };
69 |
--------------------------------------------------------------------------------
/src/modules/Request.ts:
--------------------------------------------------------------------------------
1 | import { fetch, RequestInit } from 'undici';
2 |
3 | import { JSPteroAPIError, pterodactylError } from './Error';
4 |
5 | export class Request {
6 | constructor(
7 | private readonly host: string,
8 | private readonly key: string,
9 | private readonly errorHandler: (error: JSPteroAPIError) => void
10 | ) {}
11 | /**
12 | * @param requestType - The type of request to use e. g. GET, POST
13 | * @param data - Data to send
14 | * @param dataObj - Data object to return / Text to give on success
15 | * @param endpoint - Endpoint for server to call
16 | * @param text - Boolean if we want to return text of the response
17 | */
18 | public async request(
19 | requestType: 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT',
20 | data: Record | string | unknown | null,
21 | dataObj: string,
22 | endpoint: string,
23 | text = false
24 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
25 | ): Promise {
26 | const URL = this.host + endpoint;
27 | const options: RequestInit = {
28 | method: requestType,
29 | headers: {
30 | 'responseEncoding': 'utf8',
31 | 'Authorization': 'Bearer ' + this.key,
32 | 'Content-Type': `${
33 | !endpoint.includes('files/write') ? 'application/json' : ''
34 | }`,
35 | 'Accept': 'application/json'
36 | }
37 | };
38 | if (data && endpoint.includes('files/write')) options.body = data as string;
39 | if (data && !endpoint.includes('files/write'))
40 | options.body = JSON.stringify(data);
41 | const rawData = await fetch(URL, options);
42 | if (!rawData.ok)
43 | return this.errorHandler(
44 | new JSPteroAPIError(
45 | rawData,
46 | (await rawData.json()) as pterodactylError,
47 | data as Record,
48 | requestType
49 | )
50 | );
51 | if (rawData.status === 204 || rawData.status === 202) return dataObj;
52 | if (text) return await rawData.text();
53 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
54 | let res = (await rawData.json()) as any;
55 | if (!dataObj) return res;
56 | const objArr = dataObj.split('.');
57 | objArr.forEach((obj) => {
58 | res = res[obj];
59 | });
60 | return res;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/modules/Socket.ts:
--------------------------------------------------------------------------------
1 | import { WebSocket, Event, MessageEvent, CloseEvent, ErrorEvent } from 'ws';
2 |
3 | export class Socket {
4 | constructor(
5 | private readonly url: string,
6 | private readonly options: {
7 | onopen: (this: Socket, ev: Event) => void;
8 | onmessage: (this: Socket, ev: MessageEvent) => void;
9 | onreconnect: (this: Socket, ev: Event | CloseEvent | ErrorEvent) => void;
10 | onmaximum: (this: Socket, ev: CloseEvent | ErrorEvent) => void;
11 | onclose: (this: Socket, ev: CloseEvent) => void;
12 | onerror: (this: Socket, ev: ErrorEvent) => void;
13 | }
14 | ) {
15 | this.open();
16 | }
17 |
18 | declare ws: WebSocket;
19 | declare timer: NodeJS.Timeout;
20 | private reconnectNum = 0;
21 |
22 | public open = () => {
23 | const options = this.options;
24 | const reconnect = this.reconnect;
25 | this.ws = new WebSocket(this.url);
26 |
27 | this.ws.onmessage = options.onmessage;
28 |
29 | const onOpen = options.onopen.bind(this);
30 | this.ws.onopen = (e) => {
31 | onOpen(e);
32 | this.reconnectNum = 0;
33 | };
34 |
35 | const onClose = options.onclose.bind(this);
36 | this.ws.onclose = function (e) {
37 | e.code === 1e3 || e.code === 1001 || e.code === 1005 || reconnect(e);
38 | onClose(e);
39 | };
40 |
41 | const onError = options.onerror.bind(this);
42 | this.ws.onerror = function (e) {
43 | e && (e as unknown as Record).code === 'ECONNREFUSED'
44 | ? reconnect(e)
45 | : onError(e);
46 | };
47 | };
48 |
49 | private reconnect = (e: CloseEvent | ErrorEvent) => {
50 | const onReconnect = this.options.onreconnect.bind(this);
51 | const onMaximum = this.options.onmaximum.bind(this);
52 |
53 | const open = this.open;
54 | if (this.timer && this.reconnectNum++ < Infinity) {
55 | this.timer = setTimeout(function () {
56 | onReconnect(e);
57 | open();
58 | }, 1e3);
59 | } else {
60 | onMaximum(e);
61 | }
62 | };
63 |
64 | public json = (x: unknown) => {
65 | this.ws.send(JSON.stringify(x));
66 | };
67 |
68 | public send = (x: string) => {
69 | this.ws.send(x);
70 | };
71 |
72 | public close = (x?: number, y?: string | Buffer) => {
73 | clearTimeout(this.timer);
74 | this.ws.close(x || 1e3, y);
75 | };
76 | }
77 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
4 | "module": "CommonJS" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
5 | "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
6 | "declaration": true /* Generates corresponding '.d.ts' file. */,
7 | "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */,
8 | "outDir": "./dist" /* Redirect output structure to the directory. */,
9 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
10 | "strict": true /* Enable all strict type-checking options. */,
11 | "alwaysStrict": true,
12 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
13 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
14 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
15 | },
16 | "include": ["src"],
17 | "typedocOptions": {
18 | "name": "JSPteroAPI",
19 | "entryPoints": [
20 | "src/index.ts",
21 | "src/application/interfaces",
22 | "src/client/interfaces",
23 | "src/modules/Error.ts",
24 | "src/client/Websocket.ts"
25 | ],
26 | "entryPointStrategy": "expand",
27 | "out": "docs"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
3 | "tagDefinitions": [
4 | {
5 | "tagName": "@module",
6 | "syntaxKind": "modifier"
7 | },
8 | {
9 | "tagName": "@category",
10 | "syntaxKind": "modifier"
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------