xynginc 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.
- package/README.md +303 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +278 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
- package/scripts/postinstall.js +105 -0
package/README.md
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# XyNginC - XyPriss Nginx Controller
|
|
2
|
+
|
|
3
|
+
> Production-grade Nginx and SSL management for XyPriss applications.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/xynginc)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
XyNginC (XyPriss Nginx Controller) streamlines the deployment of XyPriss applications by automating Nginx reverse proxy configuration and SSL certificate management. It eliminates the need for manual Nginx configuration editing and simplifies the production setup process into a few lines of TypeScript.
|
|
11
|
+
|
|
12
|
+
## Key Features
|
|
13
|
+
|
|
14
|
+
- **Automated Reverse Proxy**: Maps domains to local ports seamlessly.
|
|
15
|
+
- **One-Command SSL**: Integrated Let's Encrypt and Certbot support for automatic HTTPS.
|
|
16
|
+
- **Automatic Nginx Reload**: Applies configuration changes without manual service restarts.
|
|
17
|
+
- **Multi-Domain Support**: Manages multiple domains and subdomains within a single configuration.
|
|
18
|
+
- **Optimized Configuration**: Generates production-ready Nginx configuration files.
|
|
19
|
+
- **High Performance**: Core logic executed via a Rust-based CLI for speed and reliability.
|
|
20
|
+
- **Type Safety**: Full TypeScript support with comprehensive type definitions.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
Install the package via npm:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install xynginc
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The necessary binary for your architecture (Linux x64/arm64) will be downloaded automatically during installation.
|
|
31
|
+
|
|
32
|
+
### Prerequisites
|
|
33
|
+
|
|
34
|
+
- **Operating System**: Linux (Ubuntu/Debian recommended)
|
|
35
|
+
- **Node.js**: Version 18.0.0 or higher
|
|
36
|
+
- **Nginx**: Must be installed (`sudo apt install nginx`)
|
|
37
|
+
- **Certbot**: Must be installed (`sudo apt install certbot python3-certbot-nginx`)
|
|
38
|
+
|
|
39
|
+
Verify the installation and prerequisites:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
sudo npx xynginc check
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
### Basic Configuration
|
|
48
|
+
|
|
49
|
+
Integrate XyNginC into your XyPriss server:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { createServer } from "xypriss";
|
|
53
|
+
import XNCP from "xynginc";
|
|
54
|
+
|
|
55
|
+
const app = createServer({
|
|
56
|
+
plugins: {
|
|
57
|
+
register: [
|
|
58
|
+
XNCP({
|
|
59
|
+
domains: [
|
|
60
|
+
{
|
|
61
|
+
domain: "api.example.com",
|
|
62
|
+
port: 3000,
|
|
63
|
+
ssl: true,
|
|
64
|
+
email: "admin@example.com",
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
}),
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
app.start();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Multiple Domains Configuration
|
|
76
|
+
|
|
77
|
+
Configure multiple environments or services simultaneously:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
XNCP({
|
|
81
|
+
domains: [
|
|
82
|
+
{
|
|
83
|
+
domain: "api.example.com",
|
|
84
|
+
port: 3000,
|
|
85
|
+
ssl: true,
|
|
86
|
+
email: "admin@example.com",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
domain: "admin.example.com",
|
|
90
|
+
port: 3001,
|
|
91
|
+
ssl: true,
|
|
92
|
+
email: "admin@example.com",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
domain: "dev.example.com",
|
|
96
|
+
port: 3002,
|
|
97
|
+
ssl: false,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
autoReload: true,
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Dynamic Management
|
|
105
|
+
|
|
106
|
+
Manage domains programmatically at runtime:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
app.on("ready", async () => {
|
|
110
|
+
// Add a new domain
|
|
111
|
+
await app.xynginc.addDomain(
|
|
112
|
+
"new.example.com",
|
|
113
|
+
4000,
|
|
114
|
+
true,
|
|
115
|
+
"admin@example.com"
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// List configured domains
|
|
119
|
+
const domains = await app.xynginc.listDomains();
|
|
120
|
+
console.log("Configured domains:", domains);
|
|
121
|
+
|
|
122
|
+
// Validate Nginx configuration
|
|
123
|
+
const isValid = await app.xynginc.test();
|
|
124
|
+
|
|
125
|
+
// Reload Nginx service
|
|
126
|
+
await app.xynginc.reload();
|
|
127
|
+
|
|
128
|
+
// Remove a domain
|
|
129
|
+
await app.xynginc.removeDomain("old.example.com");
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## API Reference
|
|
134
|
+
|
|
135
|
+
### Plugin Options
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface XyNginCPluginOptions {
|
|
139
|
+
/** List of domains to configure */
|
|
140
|
+
domains: Array<{
|
|
141
|
+
domain: string; // Domain name (e.g., api.example.com)
|
|
142
|
+
port: number; // Local port to proxy (e.g., 3000)
|
|
143
|
+
ssl?: boolean; // Enable SSL via Let's Encrypt
|
|
144
|
+
email?: string; // Email for Let's Encrypt registration (required if ssl=true)
|
|
145
|
+
}>;
|
|
146
|
+
|
|
147
|
+
/** Automatically reload Nginx after configuration changes (default: true) */
|
|
148
|
+
autoReload?: boolean;
|
|
149
|
+
|
|
150
|
+
/** Custom path to the xynginc binary */
|
|
151
|
+
binaryPath?: string;
|
|
152
|
+
|
|
153
|
+
/** Automatically download the binary if missing (default: true) */
|
|
154
|
+
autoDownload?: boolean;
|
|
155
|
+
|
|
156
|
+
/** Specific GitHub release version to download (default: "latest") */
|
|
157
|
+
version?: string;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Server Methods
|
|
162
|
+
|
|
163
|
+
The following methods are exposed on `server.xynginc` after the plugin is registered:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// Add a domain configuration
|
|
167
|
+
await server.xynginc.addDomain(
|
|
168
|
+
domain: string,
|
|
169
|
+
port: number,
|
|
170
|
+
ssl: boolean,
|
|
171
|
+
email?: string
|
|
172
|
+
): Promise<void>
|
|
173
|
+
|
|
174
|
+
// Remove a domain configuration
|
|
175
|
+
await server.xynginc.removeDomain(domain: string): Promise<void>
|
|
176
|
+
|
|
177
|
+
// List all configured domains
|
|
178
|
+
await server.xynginc.listDomains(): Promise<string[]>
|
|
179
|
+
|
|
180
|
+
// Reload Nginx service
|
|
181
|
+
await server.xynginc.reload(): Promise<void>
|
|
182
|
+
|
|
183
|
+
// Test Nginx configuration validity
|
|
184
|
+
await server.xynginc.test(): Promise<boolean>
|
|
185
|
+
|
|
186
|
+
// Get status of managed sites
|
|
187
|
+
await server.xynginc.status(): Promise<string>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## CLI Usage
|
|
191
|
+
|
|
192
|
+
The `xynginc` command-line interface allows for direct management without the Node.js application context.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# Check prerequisites
|
|
196
|
+
sudo xynginc check
|
|
197
|
+
|
|
198
|
+
# Add a domain
|
|
199
|
+
sudo xynginc add --domain api.example.com --port 3000 --ssl --email admin@example.com
|
|
200
|
+
|
|
201
|
+
# List domains
|
|
202
|
+
sudo xynginc list
|
|
203
|
+
|
|
204
|
+
# Apply configuration from a JSON file
|
|
205
|
+
sudo xynginc apply --config config.json
|
|
206
|
+
|
|
207
|
+
# Test Nginx configuration
|
|
208
|
+
sudo xynginc test
|
|
209
|
+
|
|
210
|
+
# Reload Nginx
|
|
211
|
+
sudo xynginc reload
|
|
212
|
+
|
|
213
|
+
# Remove a domain
|
|
214
|
+
sudo xynginc remove api.example.com
|
|
215
|
+
|
|
216
|
+
# View status
|
|
217
|
+
sudo xynginc status
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Configuration File Example
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"domains": [
|
|
225
|
+
{
|
|
226
|
+
"domain": "api.example.com",
|
|
227
|
+
"port": 3000,
|
|
228
|
+
"ssl": true,
|
|
229
|
+
"email": "admin@example.com"
|
|
230
|
+
}
|
|
231
|
+
],
|
|
232
|
+
"auto_reload": true
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Architecture
|
|
237
|
+
|
|
238
|
+
The system operates through a three-tier architecture:
|
|
239
|
+
|
|
240
|
+
1. **XyPriss Application**: The Node.js application running the server.
|
|
241
|
+
2. **XyNginC Plugin**: A TypeScript wrapper that interfaces with the application and manages the binary.
|
|
242
|
+
3. **XyNginC Binary**: A Rust-based CLI tool that performs system-level operations (Nginx configuration, Certbot execution).
|
|
243
|
+
|
|
244
|
+
## Security Considerations
|
|
245
|
+
|
|
246
|
+
XyNginC requires elevated privileges to perform the following actions:
|
|
247
|
+
|
|
248
|
+
- Writing to `/etc/nginx/sites-available/`
|
|
249
|
+
- Creating symbolic links in `/etc/nginx/sites-enabled/`
|
|
250
|
+
- Executing `certbot` for SSL certificate generation
|
|
251
|
+
- Reloading the Nginx service
|
|
252
|
+
|
|
253
|
+
**Note**: Ensure your XyPriss server is started with `sudo` privileges when using this plugin, or configure `sudoers` to allow specific commands for the user.
|
|
254
|
+
|
|
255
|
+
## Troubleshooting
|
|
256
|
+
|
|
257
|
+
### Binary Not Found
|
|
258
|
+
|
|
259
|
+
If the binary fails to download automatically:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Manually trigger postinstall
|
|
263
|
+
npm run postinstall
|
|
264
|
+
|
|
265
|
+
# Or specify the path manually in options
|
|
266
|
+
XNCP({
|
|
267
|
+
binaryPath: "/usr/local/bin/xynginc",
|
|
268
|
+
autoDownload: false,
|
|
269
|
+
})
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Permission Denied
|
|
273
|
+
|
|
274
|
+
If you encounter permission errors:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Run with sudo
|
|
278
|
+
sudo node server.js
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Certbot Failure
|
|
282
|
+
|
|
283
|
+
If SSL generation fails:
|
|
284
|
+
|
|
285
|
+
1. Verify DNS propagation: `dig api.example.com`
|
|
286
|
+
2. Ensure firewall allows traffic on ports 80 and 443:
|
|
287
|
+
```bash
|
|
288
|
+
sudo ufw allow 80
|
|
289
|
+
sudo ufw allow 443
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Contributing
|
|
293
|
+
|
|
294
|
+
Contributions are welcome. Please follow the standard pull request process.
|
|
295
|
+
|
|
296
|
+
1. Clone the repository
|
|
297
|
+
2. Install dependencies
|
|
298
|
+
3. Build the Rust CLI and TypeScript package
|
|
299
|
+
4. Run tests
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface XyNginCDomainConfig {
|
|
2
|
+
domain: string;
|
|
3
|
+
port: number;
|
|
4
|
+
ssl?: boolean;
|
|
5
|
+
email?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface XyNginCConfig {
|
|
8
|
+
domains: XyNginCDomainConfig[];
|
|
9
|
+
autoReload?: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface XyNginCPluginOptions extends XyNginCConfig {
|
|
12
|
+
/** Path to the xynginc binary (auto-detected if not provided) */
|
|
13
|
+
binaryPath?: string;
|
|
14
|
+
/** Auto-download binary if not found (default: true) */
|
|
15
|
+
autoDownload?: boolean;
|
|
16
|
+
/** GitHub release version to download (default: "latest") */
|
|
17
|
+
version?: string;
|
|
18
|
+
}
|
|
19
|
+
export default function XNCP(options: XyNginCPluginOptions): import("xypriss").XyPrissPlugin;
|
|
20
|
+
export type { XyNginCPluginOptions };
|
|
21
|
+
export declare const XyNginC: typeof XNCP;
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,oBAAqB,SAAQ,aAAa;IAClD,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,EAAE,oBAAoB,mCAiEzD;AAsQD,YAAY,EAAE,oBAAoB,EAAE,CAAC;AAGrC,eAAO,MAAM,OAAO,aAAO,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
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.XyNginC = void 0;
|
|
7
|
+
exports.default = XNCP;
|
|
8
|
+
const xypriss_1 = require("xypriss");
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const util_1 = require("util");
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const https_1 = __importDefault(require("https"));
|
|
15
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
16
|
+
const BINARY_NAME = "xynginc";
|
|
17
|
+
const GITHUB_REPO = "Nehonix-Team/xynginc";
|
|
18
|
+
const BINARY_DIR = path_1.default.join(__dirname, "../bin");
|
|
19
|
+
function XNCP(options) {
|
|
20
|
+
const { domains, autoReload = true, binaryPath, autoDownload = true, version = "latest", } = options;
|
|
21
|
+
return xypriss_1.Plugin.create({
|
|
22
|
+
name: "xynginc",
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
description: "XyPriss Nginx Controller - Automatic Nginx & SSL management",
|
|
25
|
+
onRegister: async () => {
|
|
26
|
+
console.log("[XyNginC] 🔧 Registering plugin...");
|
|
27
|
+
// Validate config
|
|
28
|
+
validateConfig({ domains, autoReload });
|
|
29
|
+
},
|
|
30
|
+
onServerStart: async (server) => {
|
|
31
|
+
console.log("[XyNginC] 🚀 Initializing Nginx Controller...");
|
|
32
|
+
try {
|
|
33
|
+
// 1. Ensure binary exists
|
|
34
|
+
const binary = await ensureBinary(binaryPath, autoDownload, version);
|
|
35
|
+
console.log(`[XyNginC] ✓ Binary located: ${binary}`);
|
|
36
|
+
// 2. Check system requirements
|
|
37
|
+
console.log("[XyNginC] 🔍 Checking system requirements...");
|
|
38
|
+
await checkRequirements(binary);
|
|
39
|
+
// 3. Apply configuration
|
|
40
|
+
console.log("[XyNginC] 📋 Applying configuration...");
|
|
41
|
+
await applyConfig(binary, { domains, auto_reload: autoReload });
|
|
42
|
+
console.log("[XyNginC] ✅ Configuration applied successfully!");
|
|
43
|
+
// Expose CLI helper methods on server
|
|
44
|
+
server.xynginc = {
|
|
45
|
+
addDomain: (domain, port, ssl = false, email) => addDomain(binary, domain, port, ssl, email),
|
|
46
|
+
removeDomain: (domain) => removeDomain(binary, domain),
|
|
47
|
+
listDomains: () => listDomains(binary),
|
|
48
|
+
reload: () => reloadNginx(binary),
|
|
49
|
+
test: () => testNginx(binary),
|
|
50
|
+
status: () => getStatus(binary),
|
|
51
|
+
};
|
|
52
|
+
console.log("[XyNginC] 💡 Server methods available: server.xynginc.*");
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error("[XyNginC] ❌ Failed to initialize:", error);
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
onServerStop: async () => {
|
|
60
|
+
console.log("[XyNginC] 👋 Shutting down Nginx Controller...");
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validate the plugin configuration
|
|
66
|
+
*/
|
|
67
|
+
function validateConfig(config) {
|
|
68
|
+
if (!config.domains || config.domains.length === 0) {
|
|
69
|
+
throw new Error("[XyNginC] Configuration error: 'domains' array cannot be empty");
|
|
70
|
+
}
|
|
71
|
+
for (const domain of config.domains) {
|
|
72
|
+
if (!domain.domain || typeof domain.domain !== "string") {
|
|
73
|
+
throw new Error("[XyNginC] Configuration error: 'domain' must be a non-empty string");
|
|
74
|
+
}
|
|
75
|
+
if (!domain.port ||
|
|
76
|
+
typeof domain.port !== "number" ||
|
|
77
|
+
domain.port < 1 ||
|
|
78
|
+
domain.port > 65535) {
|
|
79
|
+
throw new Error(`[XyNginC] Configuration error: 'port' must be between 1-65535 for ${domain.domain}`);
|
|
80
|
+
}
|
|
81
|
+
if (domain.ssl && !domain.email) {
|
|
82
|
+
throw new Error(`[XyNginC] Configuration error: 'email' is required when SSL is enabled for ${domain.domain}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Ensure the binary exists (locate or download)
|
|
88
|
+
*/
|
|
89
|
+
async function ensureBinary(customPath, autoDownload, version) {
|
|
90
|
+
// 1. Try custom path
|
|
91
|
+
if (customPath && fs_1.default.existsSync(customPath)) {
|
|
92
|
+
return customPath;
|
|
93
|
+
}
|
|
94
|
+
// 2. Try PATH
|
|
95
|
+
try {
|
|
96
|
+
const { stdout } = await execAsync("which xynginc");
|
|
97
|
+
const globalPath = stdout.trim();
|
|
98
|
+
if (globalPath && fs_1.default.existsSync(globalPath)) {
|
|
99
|
+
return globalPath;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Not in PATH
|
|
104
|
+
}
|
|
105
|
+
// 3. Try local bin directory
|
|
106
|
+
const localPath = path_1.default.join(BINARY_DIR, BINARY_NAME);
|
|
107
|
+
if (fs_1.default.existsSync(localPath)) {
|
|
108
|
+
return localPath;
|
|
109
|
+
}
|
|
110
|
+
// 4. Auto-download if enabled
|
|
111
|
+
if (autoDownload) {
|
|
112
|
+
console.log("[XyNginC] 📥 Binary not found, downloading...");
|
|
113
|
+
return await downloadBinary(version);
|
|
114
|
+
}
|
|
115
|
+
throw new Error("[XyNginC] Binary not found. Install xynginc or set 'autoDownload: true'");
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Download the binary from GitHub releases
|
|
119
|
+
*/
|
|
120
|
+
async function downloadBinary(version) {
|
|
121
|
+
const platform = os_1.default.platform();
|
|
122
|
+
const arch = os_1.default.arch();
|
|
123
|
+
if (platform !== "linux") {
|
|
124
|
+
throw new Error(`[XyNginC] Unsupported platform: ${platform}. Only Linux is supported.`);
|
|
125
|
+
}
|
|
126
|
+
const binaryName = `${BINARY_NAME}-${platform}-${arch}`;
|
|
127
|
+
const downloadUrl = version === "latest"
|
|
128
|
+
? `https://github.com/${GITHUB_REPO}/releases/latest/download/${binaryName}`
|
|
129
|
+
: `https://github.com/${GITHUB_REPO}/releases/download/${version}/${binaryName}`;
|
|
130
|
+
console.log(`[XyNginC] 📦 Downloading from: ${downloadUrl}`);
|
|
131
|
+
// Create bin directory
|
|
132
|
+
if (!fs_1.default.existsSync(BINARY_DIR)) {
|
|
133
|
+
fs_1.default.mkdirSync(BINARY_DIR, { recursive: true });
|
|
134
|
+
}
|
|
135
|
+
const localPath = path_1.default.join(BINARY_DIR, BINARY_NAME);
|
|
136
|
+
return new Promise((resolve, reject) => {
|
|
137
|
+
const file = fs_1.default.createWriteStream(localPath);
|
|
138
|
+
https_1.default
|
|
139
|
+
.get(downloadUrl, (response) => {
|
|
140
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
141
|
+
// Follow redirect
|
|
142
|
+
https_1.default
|
|
143
|
+
.get(response.headers.location, (redirectResponse) => {
|
|
144
|
+
redirectResponse.pipe(file);
|
|
145
|
+
file.on("finish", () => {
|
|
146
|
+
file.close();
|
|
147
|
+
fs_1.default.chmodSync(localPath, 0o755); // Make executable
|
|
148
|
+
console.log("[XyNginC] ✓ Binary downloaded successfully");
|
|
149
|
+
resolve(localPath);
|
|
150
|
+
});
|
|
151
|
+
})
|
|
152
|
+
.on("error", reject);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
response.pipe(file);
|
|
156
|
+
file.on("finish", () => {
|
|
157
|
+
file.close();
|
|
158
|
+
fs_1.default.chmodSync(localPath, 0o755); // Make executable
|
|
159
|
+
console.log("[XyNginC] ✓ Binary downloaded successfully");
|
|
160
|
+
resolve(localPath);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
.on("error", (err) => {
|
|
165
|
+
fs_1.default.unlinkSync(localPath); // Delete partial file
|
|
166
|
+
reject(new Error(`Failed to download binary: ${err.message}`));
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Check system requirements using the binary
|
|
172
|
+
*/
|
|
173
|
+
async function checkRequirements(binaryPath) {
|
|
174
|
+
try {
|
|
175
|
+
const { stdout, stderr } = await execAsync(`sudo ${binaryPath} check`);
|
|
176
|
+
console.log(stdout);
|
|
177
|
+
if (stderr)
|
|
178
|
+
console.error(stderr);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
throw new Error(`System requirements check failed: ${error.message}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Apply configuration using the binary
|
|
186
|
+
*/
|
|
187
|
+
async function applyConfig(binaryPath, config) {
|
|
188
|
+
const configJson = JSON.stringify(config);
|
|
189
|
+
try {
|
|
190
|
+
// Pass config via stdin to avoid shell escaping issues
|
|
191
|
+
const { stdout, stderr } = await execAsync(`echo '${configJson}' | sudo ${binaryPath} apply --config -`);
|
|
192
|
+
console.log(stdout);
|
|
193
|
+
if (stderr)
|
|
194
|
+
console.error(stderr);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
throw new Error(`Failed to apply configuration: ${error.message}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Add a domain using the binary
|
|
202
|
+
*/
|
|
203
|
+
async function addDomain(binaryPath, domain, port, ssl, email) {
|
|
204
|
+
const sslFlag = ssl ? "--ssl" : "";
|
|
205
|
+
const emailFlag = email ? `--email ${email}` : "";
|
|
206
|
+
try {
|
|
207
|
+
const { stdout } = await execAsync(`sudo ${binaryPath} add --domain ${domain} --port ${port} ${sslFlag} ${emailFlag}`);
|
|
208
|
+
console.log(stdout);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
throw new Error(`Failed to add domain: ${error.message}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Remove a domain using the binary
|
|
216
|
+
*/
|
|
217
|
+
async function removeDomain(binaryPath, domain) {
|
|
218
|
+
try {
|
|
219
|
+
const { stdout } = await execAsync(`sudo ${binaryPath} remove ${domain}`);
|
|
220
|
+
console.log(stdout);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
throw new Error(`Failed to remove domain: ${error.message}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* List all configured domains
|
|
228
|
+
*/
|
|
229
|
+
async function listDomains(binaryPath) {
|
|
230
|
+
try {
|
|
231
|
+
const { stdout } = await execAsync(`sudo ${binaryPath} list`);
|
|
232
|
+
// Parse output to extract domain names
|
|
233
|
+
const lines = stdout.split("\n").filter((line) => line.includes(" - "));
|
|
234
|
+
return lines.map((line) => line.trim().split(" - ")[0]);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
throw new Error(`Failed to list domains: ${error.message}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Reload Nginx
|
|
242
|
+
*/
|
|
243
|
+
async function reloadNginx(binaryPath) {
|
|
244
|
+
try {
|
|
245
|
+
const { stdout } = await execAsync(`sudo ${binaryPath} reload`);
|
|
246
|
+
console.log(stdout);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
throw new Error(`Failed to reload Nginx: ${error.message}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Test Nginx configuration
|
|
254
|
+
*/
|
|
255
|
+
async function testNginx(binaryPath) {
|
|
256
|
+
try {
|
|
257
|
+
await execAsync(`sudo ${binaryPath} test`);
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get status
|
|
266
|
+
*/
|
|
267
|
+
async function getStatus(binaryPath) {
|
|
268
|
+
try {
|
|
269
|
+
const { stdout } = await execAsync(`sudo ${binaryPath} status`);
|
|
270
|
+
return stdout;
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
throw new Error(`Failed to get status: ${error.message}`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Named exports for direct usage
|
|
277
|
+
exports.XyNginC = XNCP;
|
|
278
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "xynginc",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "XyPriss Nginx Controller - Automatic Nginx & SSL management for XyPriss servers",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"xynginc": "./bin/xynginc"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"build:rust": "cd core && cargo build --release && cp target/release/xynginc ../bin/",
|
|
13
|
+
"build:all": "npm run build:rust && npm run build",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
16
|
+
"postinstall": "node scripts/postinstall.js"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"xypriss",
|
|
20
|
+
"nginx",
|
|
21
|
+
"ssl",
|
|
22
|
+
"certbot",
|
|
23
|
+
"reverse-proxy",
|
|
24
|
+
"letsencrypt",
|
|
25
|
+
"plugin"
|
|
26
|
+
],
|
|
27
|
+
"author": "iDevo",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"xypriss": "^1.0.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.10.0",
|
|
34
|
+
"typescript": "^5.3.0"
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"bin",
|
|
39
|
+
"scripts",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"os": [
|
|
43
|
+
"linux"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/Nehonix-Team/xynginc.git"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/Nehonix-Team/xynginc.git/issues"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const https = require("https");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const os = require("os");
|
|
7
|
+
|
|
8
|
+
const GITHUB_REPO = "Nehonix-Team/xynginc";
|
|
9
|
+
const VERSION = "latest";
|
|
10
|
+
const BIN_DIR = path.join(__dirname, "../bin");
|
|
11
|
+
const BINARY_NAME = "xynginc";
|
|
12
|
+
|
|
13
|
+
async function downloadBinary() {
|
|
14
|
+
const platform = os.platform();
|
|
15
|
+
const arch = os.arch();
|
|
16
|
+
|
|
17
|
+
// Only support Linux for now
|
|
18
|
+
if (platform !== "linux") {
|
|
19
|
+
console.log(
|
|
20
|
+
`⚠️ [XyNginC] Platform ${platform} not supported. Only Linux is supported.`
|
|
21
|
+
);
|
|
22
|
+
console.log(" You'll need to manually install the xynginc binary.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`📦 [XyNginC] Downloading binary for ${platform}-${arch}...`);
|
|
27
|
+
|
|
28
|
+
const binaryName = `${BINARY_NAME}-${platform}-${arch}`;
|
|
29
|
+
const downloadUrl =
|
|
30
|
+
VERSION === "latest"
|
|
31
|
+
? `https://github.com/${GITHUB_REPO}/releases/latest/download/${binaryName}`
|
|
32
|
+
: `https://github.com/${GITHUB_REPO}/releases/download/${VERSION}/${binaryName}`;
|
|
33
|
+
|
|
34
|
+
// Create bin directory
|
|
35
|
+
if (!fs.existsSync(BIN_DIR)) {
|
|
36
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const localPath = path.join(BIN_DIR, BINARY_NAME);
|
|
40
|
+
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const file = fs.createWriteStream(localPath);
|
|
43
|
+
|
|
44
|
+
console.log(` Downloading from: ${downloadUrl}`);
|
|
45
|
+
|
|
46
|
+
https
|
|
47
|
+
.get(downloadUrl, (response) => {
|
|
48
|
+
// Handle redirects
|
|
49
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
50
|
+
https
|
|
51
|
+
.get(response.headers.location, (redirectResponse) => {
|
|
52
|
+
if (redirectResponse.statusCode !== 200) {
|
|
53
|
+
reject(
|
|
54
|
+
new Error(
|
|
55
|
+
`Failed to download: HTTP ${redirectResponse.statusCode}`
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
redirectResponse.pipe(file);
|
|
62
|
+
file.on("finish", () => {
|
|
63
|
+
file.close();
|
|
64
|
+
fs.chmodSync(localPath, 0o755); // Make executable
|
|
65
|
+
console.log(
|
|
66
|
+
"✅ [XyNginC] Binary downloaded and installed successfully!"
|
|
67
|
+
);
|
|
68
|
+
console.log(` Location: ${localPath}`);
|
|
69
|
+
resolve();
|
|
70
|
+
});
|
|
71
|
+
})
|
|
72
|
+
.on("error", reject);
|
|
73
|
+
} else if (response.statusCode === 200) {
|
|
74
|
+
response.pipe(file);
|
|
75
|
+
file.on("finish", () => {
|
|
76
|
+
file.close();
|
|
77
|
+
fs.chmodSync(localPath, 0o755); // Make executable
|
|
78
|
+
console.log(
|
|
79
|
+
"✅ [XyNginC] Binary downloaded and installed successfully!"
|
|
80
|
+
);
|
|
81
|
+
console.log(` Location: ${localPath}`);
|
|
82
|
+
resolve();
|
|
83
|
+
});
|
|
84
|
+
} else {
|
|
85
|
+
reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
.on("error", (err) => {
|
|
89
|
+
if (fs.existsSync(localPath)) {
|
|
90
|
+
fs.unlinkSync(localPath); // Delete partial file
|
|
91
|
+
}
|
|
92
|
+
reject(err);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Run download
|
|
98
|
+
downloadBinary().catch((error) => {
|
|
99
|
+
console.error(`❌ [XyNginC] Failed to download binary: ${error.message}`);
|
|
100
|
+
console.log(" You can manually install xynginc from:");
|
|
101
|
+
console.log(` https://github.com/${GITHUB_REPO}/releases`);
|
|
102
|
+
console.log(" Or set a custom binaryPath in your plugin config.");
|
|
103
|
+
// Don't fail npm install
|
|
104
|
+
process.exit(0);
|
|
105
|
+
});
|