mofh-client-ts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +47 -0
  2. package/dist/Client.d.ts +37 -0
  3. package/dist/Client.js +174 -0
  4. package/dist/Exception/MismatchedStatusesException.d.ts +3 -0
  5. package/dist/Exception/MismatchedStatusesException.js +7 -0
  6. package/dist/Exception/MofhClientException.d.ts +3 -0
  7. package/dist/Exception/MofhClientException.js +11 -0
  8. package/dist/Exception/MofhClientHttpException.d.ts +5 -0
  9. package/dist/Exception/MofhClientHttpException.js +11 -0
  10. package/dist/Message/AbstractResponse.d.ts +10 -0
  11. package/dist/Message/AbstractResponse.js +13 -0
  12. package/dist/Message/AvailabilityResponse.d.ts +7 -0
  13. package/dist/Message/AvailabilityResponse.js +21 -0
  14. package/dist/Message/ChangePackageResponse.d.ts +3 -0
  15. package/dist/Message/ChangePackageResponse.js +7 -0
  16. package/dist/Message/CreateAccountResponse.d.ts +4 -0
  17. package/dist/Message/CreateAccountResponse.js +14 -0
  18. package/dist/Message/CreateTicketResponse.d.ts +7 -0
  19. package/dist/Message/CreateTicketResponse.js +27 -0
  20. package/dist/Message/GetCnameResponse.d.ts +7 -0
  21. package/dist/Message/GetCnameResponse.js +19 -0
  22. package/dist/Message/GetDomainUserResponse.d.ts +8 -0
  23. package/dist/Message/GetDomainUserResponse.js +22 -0
  24. package/dist/Message/GetUserDomainsResponse.d.ts +8 -0
  25. package/dist/Message/GetUserDomainsResponse.js +51 -0
  26. package/dist/Message/JsonResponse.d.ts +6 -0
  27. package/dist/Message/JsonResponse.js +41 -0
  28. package/dist/Message/ListPackagesResponse.d.ts +4 -0
  29. package/dist/Message/ListPackagesResponse.js +13 -0
  30. package/dist/Message/PasswordResponse.d.ts +9 -0
  31. package/dist/Message/PasswordResponse.js +39 -0
  32. package/dist/Message/PlainResponse.d.ts +10 -0
  33. package/dist/Message/PlainResponse.js +33 -0
  34. package/dist/Message/RemoveAccountResponse.d.ts +3 -0
  35. package/dist/Message/RemoveAccountResponse.js +7 -0
  36. package/dist/Message/ReplyTicketResponse.d.ts +6 -0
  37. package/dist/Message/ReplyTicketResponse.js +16 -0
  38. package/dist/Message/SuspendResponse.d.ts +10 -0
  39. package/dist/Message/SuspendResponse.js +30 -0
  40. package/dist/Message/UnsuspendResponse.d.ts +6 -0
  41. package/dist/Message/UnsuspendResponse.js +23 -0
  42. package/dist/Message/XmlResponse.d.ts +6 -0
  43. package/dist/Message/XmlResponse.js +44 -0
  44. package/dist/index.d.ts +21 -0
  45. package/dist/index.js +37 -0
  46. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # MOFH Client (TypeScript)
2
+
3
+ A TypeScript client for the MyOwnFreeHost (MOFH) API. This library provides a strongly-typed interface for interacting with the MOFH XML and JSON APIs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install mofh-client-ts
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { Client } from 'mofh-client-ts';
15
+
16
+ const client = new Client('your_api_username', 'your_api_password');
17
+
18
+ // Example: Check domain availability
19
+ const availability = await client.availability('example.com');
20
+ if (availability.isAvailable()) {
21
+ console.log('Domain is available!');
22
+ }
23
+
24
+ // Example: Create an account
25
+ const account = await client.createAccount('user123', 'password', 'email@example.com', 'example.com', 'Plan1');
26
+ if (account.isSuccessful()) {
27
+ console.log('Account created:', account.getVpUsername());
28
+ } else {
29
+ console.error('Error:', account.getMessage());
30
+ }
31
+ ```
32
+
33
+ ## Features
34
+
35
+ - Full TypeScript support with type definitions.
36
+ - Promise-based API using `axios`.
37
+ - Support for all major MOFH API endpoints:
38
+ - Create/Suspend/Unsuspend/Remove Account
39
+ - Change Password/Package
40
+ - Check Availability
41
+ - Get User Domains/Domain User
42
+ - Support Tickets (Create/Reply)
43
+ - CNAME Verification
44
+
45
+ ## License
46
+
47
+ MIT
@@ -0,0 +1,37 @@
1
+ import { AxiosInstance, AxiosResponse } from 'axios';
2
+ import { AvailabilityResponse } from './Message/AvailabilityResponse';
3
+ import { ChangePackageResponse } from './Message/ChangePackageResponse';
4
+ import { CreateAccountResponse } from './Message/CreateAccountResponse';
5
+ import { CreateTicketResponse } from './Message/CreateTicketResponse';
6
+ import { GetCnameResponse } from './Message/GetCnameResponse';
7
+ import { GetDomainUserResponse } from './Message/GetDomainUserResponse';
8
+ import { GetUserDomainsResponse } from './Message/GetUserDomainsResponse';
9
+ import { ListPackagesResponse } from './Message/ListPackagesResponse';
10
+ import { PasswordResponse } from './Message/PasswordResponse';
11
+ import { RemoveAccountResponse } from './Message/RemoveAccountResponse';
12
+ import { ReplyTicketResponse } from './Message/ReplyTicketResponse';
13
+ import { SuspendResponse } from './Message/SuspendResponse';
14
+ import { UnsuspendResponse } from './Message/UnsuspendResponse';
15
+ export declare class Client {
16
+ protected httpClient: AxiosInstance;
17
+ protected apiUsername: string;
18
+ protected apiPassword: string;
19
+ protected apiUrl: string;
20
+ constructor(apiUsername: string, apiPassword: string, apiUrl?: string, httpClient?: AxiosInstance);
21
+ protected sendPostRequest(path: string, parameters: any, timeout?: number): Promise<AxiosResponse>;
22
+ protected sendGetRequest(path: string, parameters: any, timeout?: number): Promise<AxiosResponse>;
23
+ private sendRawRequest;
24
+ createAccount(username: string, password: string, email: string, domain: string, plan: string): Promise<CreateAccountResponse>;
25
+ suspend(username: string, reason: string, linked?: boolean): Promise<SuspendResponse>;
26
+ unsuspend(username: string): Promise<UnsuspendResponse>;
27
+ password(username: string, password: string): Promise<PasswordResponse>;
28
+ availability(domain: string): Promise<AvailabilityResponse>;
29
+ getUserDomains(username: string): Promise<GetUserDomainsResponse>;
30
+ getDomainUser(domain: string): Promise<GetDomainUserResponse>;
31
+ getCname(domain: string): Promise<GetCnameResponse>;
32
+ listPackages(): Promise<ListPackagesResponse>;
33
+ removeAccount(username: string): Promise<RemoveAccountResponse>;
34
+ changePackage(username: string, packageName: string): Promise<ChangePackageResponse>;
35
+ createTicket(subject: string, comments: string, domain: string, username: string, ipAddress: string): Promise<CreateTicketResponse>;
36
+ replyTicket(ticketId: string, comments: string, username: string, ipAddress: string, domain?: string | null): Promise<ReplyTicketResponse>;
37
+ }
package/dist/Client.js ADDED
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Client = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const MofhClientHttpException_1 = require("./Exception/MofhClientHttpException");
9
+ const AvailabilityResponse_1 = require("./Message/AvailabilityResponse");
10
+ const ChangePackageResponse_1 = require("./Message/ChangePackageResponse");
11
+ const CreateAccountResponse_1 = require("./Message/CreateAccountResponse");
12
+ const CreateTicketResponse_1 = require("./Message/CreateTicketResponse");
13
+ const GetCnameResponse_1 = require("./Message/GetCnameResponse");
14
+ const GetDomainUserResponse_1 = require("./Message/GetDomainUserResponse");
15
+ const GetUserDomainsResponse_1 = require("./Message/GetUserDomainsResponse");
16
+ const ListPackagesResponse_1 = require("./Message/ListPackagesResponse");
17
+ const PasswordResponse_1 = require("./Message/PasswordResponse");
18
+ const RemoveAccountResponse_1 = require("./Message/RemoveAccountResponse");
19
+ const ReplyTicketResponse_1 = require("./Message/ReplyTicketResponse");
20
+ const SuspendResponse_1 = require("./Message/SuspendResponse");
21
+ const UnsuspendResponse_1 = require("./Message/UnsuspendResponse");
22
+ class Client {
23
+ constructor(apiUsername, apiPassword, apiUrl = 'https://panel.myownfreehost.net', httpClient) {
24
+ this.apiUsername = apiUsername;
25
+ this.apiPassword = apiPassword;
26
+ if (apiUrl.endsWith('/')) {
27
+ apiUrl = apiUrl.slice(0, -1);
28
+ }
29
+ if (apiUrl.endsWith('/xml-api')) {
30
+ apiUrl = apiUrl.slice(0, -8);
31
+ }
32
+ this.apiUrl = apiUrl;
33
+ this.httpClient = httpClient || axios_1.default.create({
34
+ timeout: 5000,
35
+ });
36
+ }
37
+ async sendPostRequest(path, parameters, timeout = 60000) {
38
+ return this.sendRawRequest('POST', path, {
39
+ headers: {
40
+ 'Content-Type': 'application/x-www-form-urlencoded'
41
+ },
42
+ data: new URLSearchParams(parameters),
43
+ auth: {
44
+ username: this.apiUsername,
45
+ password: this.apiPassword
46
+ },
47
+ timeout: timeout,
48
+ });
49
+ }
50
+ async sendGetRequest(path, parameters, timeout = 10000) {
51
+ return this.sendRawRequest('GET', path, {
52
+ params: {
53
+ api_user: this.apiUsername,
54
+ api_key: this.apiPassword,
55
+ ...parameters
56
+ },
57
+ timeout: timeout,
58
+ });
59
+ }
60
+ async sendRawRequest(method, url, requestOptions = {}) {
61
+ try {
62
+ return await this.httpClient.request({
63
+ method: method,
64
+ url: `${this.apiUrl}${url}`,
65
+ ...requestOptions
66
+ });
67
+ }
68
+ catch (e) {
69
+ throw new MofhClientHttpException_1.MofhClientHttpException('The MOFH API returned a HTTP error: ' + (e.message || e), 0, e);
70
+ }
71
+ }
72
+ async createAccount(username, password, email, domain, plan) {
73
+ const response = await this.sendPostRequest('/xml-api/createacct', {
74
+ username: username,
75
+ password: password,
76
+ contactemail: email,
77
+ domain: domain,
78
+ plan: plan,
79
+ });
80
+ return new CreateAccountResponse_1.CreateAccountResponse(response);
81
+ }
82
+ async suspend(username, reason, linked = false) {
83
+ const response = await this.sendPostRequest('/xml-api/suspendacct', {
84
+ user: username,
85
+ reason: reason,
86
+ linked: linked ? '1' : '0',
87
+ });
88
+ return new SuspendResponse_1.SuspendResponse(response);
89
+ }
90
+ async unsuspend(username) {
91
+ const response = await this.sendPostRequest('/xml-api/unsuspendacct', {
92
+ user: username,
93
+ });
94
+ return new UnsuspendResponse_1.UnsuspendResponse(response);
95
+ }
96
+ async password(username, password) {
97
+ const response = await this.sendPostRequest('/xml-api/passwd', {
98
+ user: username,
99
+ pass: password,
100
+ });
101
+ return new PasswordResponse_1.PasswordResponse(response);
102
+ }
103
+ async availability(domain) {
104
+ const response = await this.sendGetRequest('/xml-api/checkavailable', {
105
+ domain: domain,
106
+ });
107
+ return new AvailabilityResponse_1.AvailabilityResponse(response);
108
+ }
109
+ async getUserDomains(username) {
110
+ const response = await this.sendGetRequest('/json-api/getuserdomains', {
111
+ username: username,
112
+ });
113
+ return new GetUserDomainsResponse_1.GetUserDomainsResponse(response);
114
+ }
115
+ async getDomainUser(domain) {
116
+ const response = await this.sendGetRequest('/json-api/getdomainuser', {
117
+ domain: domain,
118
+ });
119
+ return new GetDomainUserResponse_1.GetDomainUserResponse(response);
120
+ }
121
+ async getCname(domain) {
122
+ const response = await this.sendPostRequest('/xml-api/getcname', {
123
+ api_user: this.apiUsername,
124
+ api_key: this.apiPassword,
125
+ domain_name: domain,
126
+ });
127
+ return new GetCnameResponse_1.GetCnameResponse(response);
128
+ }
129
+ async listPackages() {
130
+ const response = await this.sendGetRequest('/json-api/listpkgs', {});
131
+ return new ListPackagesResponse_1.ListPackagesResponse(response);
132
+ }
133
+ async removeAccount(username) {
134
+ const response = await this.sendPostRequest('/xml-api/removeacct', {
135
+ user: username,
136
+ });
137
+ return new RemoveAccountResponse_1.RemoveAccountResponse(response);
138
+ }
139
+ async changePackage(username, packageName) {
140
+ const response = await this.sendPostRequest('/xml-api/changepackage', {
141
+ user: username,
142
+ pkg: packageName.toLowerCase(),
143
+ });
144
+ return new ChangePackageResponse_1.ChangePackageResponse(response);
145
+ }
146
+ async createTicket(subject, comments, domain, username, ipAddress) {
147
+ const response = await this.sendPostRequest('/xml-api/supportnewticket', {
148
+ api_user: this.apiUsername,
149
+ api_key: this.apiPassword,
150
+ comments: comments,
151
+ subject: subject,
152
+ domain_name: domain,
153
+ ipaddress: ipAddress,
154
+ clientusername: username,
155
+ });
156
+ return new CreateTicketResponse_1.CreateTicketResponse(response);
157
+ }
158
+ async replyTicket(ticketId, comments, username, ipAddress, domain = null) {
159
+ const params = {
160
+ api_user: this.apiUsername,
161
+ api_key: this.apiPassword,
162
+ comments: comments,
163
+ ipaddress: ipAddress,
164
+ clientusername: username,
165
+ ticket_id: ticketId,
166
+ };
167
+ if (domain) {
168
+ params.domain_name = domain;
169
+ }
170
+ const response = await this.sendPostRequest('/xml-api/supportreplyticket', params);
171
+ return new ReplyTicketResponse_1.ReplyTicketResponse(response);
172
+ }
173
+ }
174
+ exports.Client = Client;
@@ -0,0 +1,3 @@
1
+ import { MofhClientException } from './MofhClientException';
2
+ export declare class MismatchedStatusesException extends MofhClientException {
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MismatchedStatusesException = void 0;
4
+ const MofhClientException_1 = require("./MofhClientException");
5
+ class MismatchedStatusesException extends MofhClientException_1.MofhClientException {
6
+ }
7
+ exports.MismatchedStatusesException = MismatchedStatusesException;
@@ -0,0 +1,3 @@
1
+ export declare class MofhClientException extends Error {
2
+ constructor(message: string);
3
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MofhClientException = void 0;
4
+ class MofhClientException extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = this.constructor.name;
8
+ Object.setPrototypeOf(this, new.target.prototype); // Restore prototype chain
9
+ }
10
+ }
11
+ exports.MofhClientException = MofhClientException;
@@ -0,0 +1,5 @@
1
+ import { MofhClientException } from './MofhClientException';
2
+ export declare class MofhClientHttpException extends MofhClientException {
3
+ originalError: any;
4
+ constructor(message: string, code?: number, previous?: any);
5
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MofhClientHttpException = void 0;
4
+ const MofhClientException_1 = require("./MofhClientException");
5
+ class MofhClientHttpException extends MofhClientException_1.MofhClientException {
6
+ constructor(message, code = 0, previous) {
7
+ super(message);
8
+ this.originalError = previous;
9
+ }
10
+ }
11
+ exports.MofhClientHttpException = MofhClientHttpException;
@@ -0,0 +1,10 @@
1
+ import { AxiosResponse } from 'axios';
2
+ export declare abstract class AbstractResponse {
3
+ protected data: any;
4
+ protected response: AxiosResponse;
5
+ constructor(response: AxiosResponse);
6
+ protected abstract parseResponse(): void;
7
+ getData(): any;
8
+ abstract isSuccessful(): boolean;
9
+ abstract getMessage(): string | null;
10
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractResponse = void 0;
4
+ class AbstractResponse {
5
+ constructor(response) {
6
+ this.response = response;
7
+ this.parseResponse();
8
+ }
9
+ getData() {
10
+ return this.data;
11
+ }
12
+ }
13
+ exports.AbstractResponse = AbstractResponse;
@@ -0,0 +1,7 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare class AvailabilityResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ getMessage(): string | null;
5
+ isSuccessful(): boolean;
6
+ isAvailable(): boolean;
7
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AvailabilityResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class AvailabilityResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ // data should be string '0' or '1'
8
+ const data = this.response.data;
9
+ this.data = typeof data === 'string' ? data.trim() : String(data).trim();
10
+ }
11
+ getMessage() {
12
+ return this.isSuccessful() ? null : this.getData();
13
+ }
14
+ isSuccessful() {
15
+ return ['0', '1'].includes(this.data);
16
+ }
17
+ isAvailable() {
18
+ return this.data === '1';
19
+ }
20
+ }
21
+ exports.AvailabilityResponse = AvailabilityResponse;
@@ -0,0 +1,3 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class ChangePackageResponse extends XmlResponse {
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChangePackageResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class ChangePackageResponse extends XmlResponse_1.XmlResponse {
6
+ }
7
+ exports.ChangePackageResponse = ChangePackageResponse;
@@ -0,0 +1,4 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class CreateAccountResponse extends XmlResponse {
3
+ getVpUsername(): string | null;
4
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateAccountResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class CreateAccountResponse extends XmlResponse_1.XmlResponse {
6
+ getVpUsername() {
7
+ const data = this.getData();
8
+ if (data && data.result && data.result.options && data.result.options.vpusername) {
9
+ return String(data.result.options.vpusername);
10
+ }
11
+ return null;
12
+ }
13
+ }
14
+ exports.CreateAccountResponse = CreateAccountResponse;
@@ -0,0 +1,7 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare class CreateTicketResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ isSuccessful(): boolean;
5
+ getMessage(): string | null;
6
+ getTicketId(): string | null;
7
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateTicketResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class CreateTicketResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ this.data = String(this.response.data);
8
+ }
9
+ isSuccessful() {
10
+ return String(this.data).includes('SUCCESS');
11
+ }
12
+ getMessage() {
13
+ return this.isSuccessful() ? null : String(this.getData());
14
+ }
15
+ getTicketId() {
16
+ if (this.isSuccessful()) {
17
+ const dataStr = String(this.data);
18
+ const successPart = dataStr.substring(dataStr.indexOf('SUCCESS'));
19
+ const parts = successPart.split(':');
20
+ return parts[1] ? parts[1].trim() : null;
21
+ }
22
+ else {
23
+ return null;
24
+ }
25
+ }
26
+ }
27
+ exports.CreateTicketResponse = CreateTicketResponse;
@@ -0,0 +1,7 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare class GetCnameResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ isSuccessful(): boolean;
5
+ getMessage(): string | null;
6
+ getCname(): string | null;
7
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetCnameResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class GetCnameResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ this.data = String(this.response.data);
8
+ }
9
+ isSuccessful() {
10
+ return String(this.data).indexOf('ERROR') !== 0;
11
+ }
12
+ getMessage() {
13
+ return this.isSuccessful() ? null : this.getData();
14
+ }
15
+ getCname() {
16
+ return this.isSuccessful() ? this.getData() : null;
17
+ }
18
+ }
19
+ exports.GetCnameResponse = GetCnameResponse;
@@ -0,0 +1,8 @@
1
+ import { PlainResponse } from './PlainResponse';
2
+ export declare class GetDomainUserResponse extends PlainResponse {
3
+ isFound(): boolean;
4
+ getDomain(): string | undefined;
5
+ getStatus(): string | undefined;
6
+ getDocumentRoot(): string | undefined;
7
+ getUsername(): string | undefined;
8
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetDomainUserResponse = void 0;
4
+ const PlainResponse_1 = require("./PlainResponse");
5
+ class GetDomainUserResponse extends PlainResponse_1.PlainResponse {
6
+ isFound() {
7
+ return Array.isArray(this.data) && this.data.length > 0;
8
+ }
9
+ getDomain() {
10
+ return this.domain;
11
+ }
12
+ getStatus() {
13
+ return this.status;
14
+ }
15
+ getDocumentRoot() {
16
+ return this.documentRoot;
17
+ }
18
+ getUsername() {
19
+ return this.username;
20
+ }
21
+ }
22
+ exports.GetDomainUserResponse = GetDomainUserResponse;
@@ -0,0 +1,8 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare class GetUserDomainsResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ getMessage(): string | null;
5
+ isSuccessful(): boolean;
6
+ getDomains(): string[];
7
+ getStatus(): string | null;
8
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetUserDomainsResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ const MismatchedStatusesException_1 = require("../Exception/MismatchedStatusesException");
6
+ class GetUserDomainsResponse extends AbstractResponse_1.AbstractResponse {
7
+ parseResponse() {
8
+ const responseBody = typeof this.response.data === 'string' ? this.response.data : JSON.stringify(this.response.data);
9
+ if (responseBody.startsWith('[')) {
10
+ try {
11
+ this.data = JSON.parse(responseBody);
12
+ }
13
+ catch (e) {
14
+ this.data = responseBody.trim();
15
+ }
16
+ }
17
+ else if (responseBody === 'null') {
18
+ this.data = [];
19
+ }
20
+ else {
21
+ this.data = responseBody.trim();
22
+ }
23
+ }
24
+ getMessage() {
25
+ return this.isSuccessful() ? null : String(this.getData());
26
+ }
27
+ isSuccessful() {
28
+ return Array.isArray(this.data);
29
+ }
30
+ getDomains() {
31
+ if (!Array.isArray(this.data))
32
+ return [];
33
+ return this.data.map((item) => item[1]);
34
+ }
35
+ getStatus() {
36
+ if (Array.isArray(this.data) && this.data.length > 0) {
37
+ const statuses = [...new Set(this.data.map((item) => item[0]))];
38
+ if (statuses.length === 1) {
39
+ return String(statuses[0]);
40
+ }
41
+ else if (statuses.length > 1) {
42
+ throw new MismatchedStatusesException_1.MismatchedStatusesException('The account domains have different statuses: ' + statuses.join(', '));
43
+ }
44
+ else {
45
+ return null;
46
+ }
47
+ }
48
+ return null;
49
+ }
50
+ }
51
+ exports.GetUserDomainsResponse = GetUserDomainsResponse;
@@ -0,0 +1,6 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare abstract class JsonResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ getMessage(): string | null;
5
+ isSuccessful(): boolean;
6
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class JsonResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ const data = this.response.data;
8
+ // Axios handles JSON parsing automatically if content-type is json
9
+ if (typeof data === 'object') {
10
+ this.data = data;
11
+ }
12
+ else {
13
+ try {
14
+ this.data = JSON.parse(data);
15
+ }
16
+ catch (e) {
17
+ this.data = typeof data === 'string' ? data.trim() : data;
18
+ }
19
+ }
20
+ }
21
+ getMessage() {
22
+ if (this.isSuccessful()) {
23
+ return null;
24
+ }
25
+ else if (this.getData() && this.getData().cpanelresult && this.getData().cpanelresult.error) {
26
+ return String(this.getData().cpanelresult.error).trim();
27
+ }
28
+ else {
29
+ return typeof this.response.data === 'string' ? this.response.data.trim() : JSON.stringify(this.response.data);
30
+ }
31
+ }
32
+ isSuccessful() {
33
+ if (this.getData()) {
34
+ return !(this.getData().cpanelresult && this.getData().cpanelresult.error);
35
+ }
36
+ else {
37
+ return false;
38
+ }
39
+ }
40
+ }
41
+ exports.JsonResponse = JsonResponse;
@@ -0,0 +1,4 @@
1
+ import { JsonResponse } from './JsonResponse';
2
+ export declare class ListPackagesResponse extends JsonResponse {
3
+ getPackages(): string[] | null;
4
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListPackagesResponse = void 0;
4
+ const JsonResponse_1 = require("./JsonResponse");
5
+ class ListPackagesResponse extends JsonResponse_1.JsonResponse {
6
+ getPackages() {
7
+ if (this.isSuccessful() && this.getData() && this.getData().packages) {
8
+ return this.getData().packages;
9
+ }
10
+ return null;
11
+ }
12
+ }
13
+ exports.ListPackagesResponse = ListPackagesResponse;
@@ -0,0 +1,9 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class PasswordResponse extends XmlResponse {
3
+ protected status: string | undefined;
4
+ protected message: string | undefined;
5
+ protected parseResponse(): void;
6
+ getMessage(): string | null;
7
+ isSuccessful(): boolean;
8
+ getStatus(): string | null;
9
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PasswordResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class PasswordResponse extends XmlResponse_1.XmlResponse {
6
+ parseResponse() {
7
+ super.parseResponse();
8
+ const data = this.getData();
9
+ if (data && data.passwd && typeof data.passwd.status !== 'undefined') {
10
+ if (data.passwd.status == '1') {
11
+ this.status = 'a';
12
+ }
13
+ else if (data.passwd.statusmsg && String(data.passwd.statusmsg).includes('error occured changing this password')) {
14
+ // Idempotent success
15
+ this.status = 'a';
16
+ }
17
+ else {
18
+ this.message = String(data.passwd.statusmsg).trim();
19
+ const match = this.message.match(/the account must be active to change the password\s*\(([^)]+)\)/i);
20
+ if (match) {
21
+ this.status = match[1];
22
+ }
23
+ }
24
+ }
25
+ else {
26
+ this.message = typeof this.response.data === 'string' ? this.response.data.trim() : JSON.stringify(this.response.data);
27
+ }
28
+ }
29
+ getMessage() {
30
+ return this.message || null;
31
+ }
32
+ isSuccessful() {
33
+ return this.status === 'a';
34
+ }
35
+ getStatus() {
36
+ return this.status || null;
37
+ }
38
+ }
39
+ exports.PasswordResponse = PasswordResponse;
@@ -0,0 +1,10 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare abstract class PlainResponse extends AbstractResponse {
3
+ protected status: string | undefined;
4
+ protected domain: string | undefined;
5
+ protected documentRoot: string | undefined;
6
+ protected username: string | undefined;
7
+ protected parseResponse(): void;
8
+ getMessage(): string | null;
9
+ isSuccessful(): boolean;
10
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PlainResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class PlainResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ const responseBody = typeof this.response.data === 'string' ? this.response.data : JSON.stringify(this.response.data);
8
+ if (responseBody.startsWith('[')) {
9
+ try {
10
+ this.data = JSON.parse(responseBody);
11
+ if (Array.isArray(this.data) && this.data.length === 4) {
12
+ [this.status, this.domain, this.documentRoot, this.username] = this.data;
13
+ }
14
+ }
15
+ catch (e) {
16
+ this.data = responseBody.trim();
17
+ }
18
+ }
19
+ else if (responseBody === 'null') {
20
+ this.data = [];
21
+ }
22
+ else {
23
+ this.data = responseBody.trim();
24
+ }
25
+ }
26
+ getMessage() {
27
+ return this.isSuccessful() ? null : String(this.getData());
28
+ }
29
+ isSuccessful() {
30
+ return Array.isArray(this.data);
31
+ }
32
+ }
33
+ exports.PlainResponse = PlainResponse;
@@ -0,0 +1,3 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class RemoveAccountResponse extends XmlResponse {
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RemoveAccountResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class RemoveAccountResponse extends XmlResponse_1.XmlResponse {
6
+ }
7
+ exports.RemoveAccountResponse = RemoveAccountResponse;
@@ -0,0 +1,6 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare class ReplyTicketResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ isSuccessful(): boolean;
5
+ getMessage(): string | null;
6
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReplyTicketResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ class ReplyTicketResponse extends AbstractResponse_1.AbstractResponse {
6
+ parseResponse() {
7
+ this.data = String(this.response.data);
8
+ }
9
+ isSuccessful() {
10
+ return String(this.getData()).includes('SUCCESS');
11
+ }
12
+ getMessage() {
13
+ return this.isSuccessful() ? null : String(this.getData());
14
+ }
15
+ }
16
+ exports.ReplyTicketResponse = ReplyTicketResponse;
@@ -0,0 +1,10 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class SuspendResponse extends XmlResponse {
3
+ protected username: string | undefined;
4
+ protected status: string | undefined;
5
+ protected reason: string | undefined;
6
+ protected parseResponse(): void;
7
+ getStatus(): string | null;
8
+ getVpUsername(): string | null;
9
+ getReason(): string | null;
10
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SuspendResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class SuspendResponse extends XmlResponse_1.XmlResponse {
6
+ parseResponse() {
7
+ super.parseResponse();
8
+ if (!this.isSuccessful()) {
9
+ const message = this.getMessage();
10
+ if (message) {
11
+ const match = message.match(/This account is not active so can not be suspended \( vPuser : (\S+) , status : (\S+) , reason : (.*) \) ../s);
12
+ if (match) {
13
+ this.username = match[1].trim();
14
+ this.status = match[2].trim();
15
+ this.reason = match[3].trim();
16
+ }
17
+ }
18
+ }
19
+ }
20
+ getStatus() {
21
+ return this.status || null;
22
+ }
23
+ getVpUsername() {
24
+ return this.username || null;
25
+ }
26
+ getReason() {
27
+ return this.reason || null;
28
+ }
29
+ }
30
+ exports.SuspendResponse = SuspendResponse;
@@ -0,0 +1,6 @@
1
+ import { XmlResponse } from './XmlResponse';
2
+ export declare class UnsuspendResponse extends XmlResponse {
3
+ protected status: string | undefined;
4
+ protected parseResponse(): void;
5
+ getStatus(): string | null;
6
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnsuspendResponse = void 0;
4
+ const XmlResponse_1 = require("./XmlResponse");
5
+ class UnsuspendResponse extends XmlResponse_1.XmlResponse {
6
+ parseResponse() {
7
+ super.parseResponse();
8
+ if (!this.isSuccessful()) {
9
+ const message = this.getMessage();
10
+ if (message) {
11
+ const match = message.match(/account is NOT currently suspended \(status : (\w*) \)/);
12
+ if (match) {
13
+ const status = match[1].trim();
14
+ this.status = status === '' ? 'd' : status;
15
+ }
16
+ }
17
+ }
18
+ }
19
+ getStatus() {
20
+ return this.status || null;
21
+ }
22
+ }
23
+ exports.UnsuspendResponse = UnsuspendResponse;
@@ -0,0 +1,6 @@
1
+ import { AbstractResponse } from './AbstractResponse';
2
+ export declare abstract class XmlResponse extends AbstractResponse {
3
+ protected parseResponse(): void;
4
+ getMessage(): string | null;
5
+ isSuccessful(): boolean;
6
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.XmlResponse = void 0;
4
+ const AbstractResponse_1 = require("./AbstractResponse");
5
+ const fast_xml_parser_1 = require("fast-xml-parser");
6
+ class XmlResponse extends AbstractResponse_1.AbstractResponse {
7
+ parseResponse() {
8
+ const data = this.response.data;
9
+ const parser = new fast_xml_parser_1.XMLParser({
10
+ ignoreAttributes: false,
11
+ attributeNamePrefix: "@_"
12
+ });
13
+ try {
14
+ // Axios might automatically parse JSON, but for XML it returns string usually.
15
+ const xmlString = typeof data === 'string' ? data : String(data);
16
+ // simplexml_load_string logic roughly translated
17
+ const xmlData = parser.parse(xmlString);
18
+ this.data = xmlData;
19
+ }
20
+ catch (e) {
21
+ this.data = typeof data === 'string' ? data.trim() : data;
22
+ }
23
+ }
24
+ getMessage() {
25
+ if (this.isSuccessful()) {
26
+ return null;
27
+ }
28
+ else if (this.getData() && this.getData().result && this.getData().result.statusmsg) {
29
+ return String(this.getData().result.statusmsg).trim();
30
+ }
31
+ else {
32
+ return typeof this.response.data === 'string' ? this.response.data.trim() : JSON.stringify(this.response.data);
33
+ }
34
+ }
35
+ isSuccessful() {
36
+ if (this.getData() && this.getData().result && this.getData().result.status) {
37
+ return this.getData().result.status == 1;
38
+ }
39
+ else {
40
+ return false;
41
+ }
42
+ }
43
+ }
44
+ exports.XmlResponse = XmlResponse;
@@ -0,0 +1,21 @@
1
+ export * from './Exception/MofhClientException';
2
+ export * from './Exception/MofhClientHttpException';
3
+ export * from './Exception/MismatchedStatusesException';
4
+ export * from './Message/AbstractResponse';
5
+ export * from './Message/XmlResponse';
6
+ export * from './Message/JsonResponse';
7
+ export * from './Message/PlainResponse';
8
+ export * from './Message/AvailabilityResponse';
9
+ export * from './Message/ChangePackageResponse';
10
+ export * from './Message/CreateAccountResponse';
11
+ export * from './Message/CreateTicketResponse';
12
+ export * from './Message/GetCnameResponse';
13
+ export * from './Message/GetDomainUserResponse';
14
+ export * from './Message/GetUserDomainsResponse';
15
+ export * from './Message/ListPackagesResponse';
16
+ export * from './Message/PasswordResponse';
17
+ export * from './Message/RemoveAccountResponse';
18
+ export * from './Message/ReplyTicketResponse';
19
+ export * from './Message/SuspendResponse';
20
+ export * from './Message/UnsuspendResponse';
21
+ export * from './Client';
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Exception/MofhClientException"), exports);
18
+ __exportStar(require("./Exception/MofhClientHttpException"), exports);
19
+ __exportStar(require("./Exception/MismatchedStatusesException"), exports);
20
+ __exportStar(require("./Message/AbstractResponse"), exports);
21
+ __exportStar(require("./Message/XmlResponse"), exports);
22
+ __exportStar(require("./Message/JsonResponse"), exports);
23
+ __exportStar(require("./Message/PlainResponse"), exports);
24
+ __exportStar(require("./Message/AvailabilityResponse"), exports);
25
+ __exportStar(require("./Message/ChangePackageResponse"), exports);
26
+ __exportStar(require("./Message/CreateAccountResponse"), exports);
27
+ __exportStar(require("./Message/CreateTicketResponse"), exports);
28
+ __exportStar(require("./Message/GetCnameResponse"), exports);
29
+ __exportStar(require("./Message/GetDomainUserResponse"), exports);
30
+ __exportStar(require("./Message/GetUserDomainsResponse"), exports);
31
+ __exportStar(require("./Message/ListPackagesResponse"), exports);
32
+ __exportStar(require("./Message/PasswordResponse"), exports);
33
+ __exportStar(require("./Message/RemoveAccountResponse"), exports);
34
+ __exportStar(require("./Message/ReplyTicketResponse"), exports);
35
+ __exportStar(require("./Message/SuspendResponse"), exports);
36
+ __exportStar(require("./Message/UnsuspendResponse"), exports);
37
+ __exportStar(require("./Client"), exports);
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "mofh-client-ts",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript MOFH Client",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "keywords": [
11
+ "mofh",
12
+ "myownfreehost",
13
+ "client",
14
+ "api",
15
+ "typescript"
16
+ ],
17
+ "author": "Mehtab Hassan",
18
+ "license": "MIT",
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "test": "jest",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "dependencies": {
25
+ "axios": "^1.6.0",
26
+ "fast-xml-parser": "^4.3.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/jest": "^30.0.0",
30
+ "@types/node": "^20.19.33",
31
+ "jest": "^30.2.0",
32
+ "ts-jest": "^29.4.6",
33
+ "typescript": "^5.0.0"
34
+ }
35
+ }