vps-deployer 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 (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/app.d.ts +4 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +39 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/db/db.d.ts +5 -0
  8. package/dist/db/db.d.ts.map +1 -0
  9. package/dist/db/db.js +100 -0
  10. package/dist/db/db.js.map +1 -0
  11. package/dist/helpers/arg.helper.d.ts +7 -0
  12. package/dist/helpers/arg.helper.d.ts.map +1 -0
  13. package/dist/helpers/arg.helper.js +28 -0
  14. package/dist/helpers/arg.helper.js.map +1 -0
  15. package/dist/helpers/cmd_executer.helper.d.ts +7 -0
  16. package/dist/helpers/cmd_executer.helper.d.ts.map +1 -0
  17. package/dist/helpers/cmd_executer.helper.js +88 -0
  18. package/dist/helpers/cmd_executer.helper.js.map +1 -0
  19. package/dist/helpers/common.helper.d.ts +2 -0
  20. package/dist/helpers/common.helper.d.ts.map +1 -0
  21. package/dist/helpers/common.helper.js +15 -0
  22. package/dist/helpers/common.helper.js.map +1 -0
  23. package/dist/helpers/config_files.helper.d.ts +2 -0
  24. package/dist/helpers/config_files.helper.d.ts.map +1 -0
  25. package/dist/helpers/config_files.helper.js +44 -0
  26. package/dist/helpers/config_files.helper.js.map +1 -0
  27. package/dist/helpers/create_systemd_service.helper.d.ts +9 -0
  28. package/dist/helpers/create_systemd_service.helper.d.ts.map +1 -0
  29. package/dist/helpers/create_systemd_service.helper.js +40 -0
  30. package/dist/helpers/create_systemd_service.helper.js.map +1 -0
  31. package/dist/helpers/date.helper.d.ts +2 -0
  32. package/dist/helpers/date.helper.d.ts.map +1 -0
  33. package/dist/helpers/date.helper.js +18 -0
  34. package/dist/helpers/date.helper.js.map +1 -0
  35. package/dist/helpers/email.helper.d.ts +11 -0
  36. package/dist/helpers/email.helper.d.ts.map +1 -0
  37. package/dist/helpers/email.helper.js +144 -0
  38. package/dist/helpers/email.helper.js.map +1 -0
  39. package/dist/helpers/logging.helper.d.ts +9 -0
  40. package/dist/helpers/logging.helper.d.ts.map +1 -0
  41. package/dist/helpers/logging.helper.js +32 -0
  42. package/dist/helpers/logging.helper.js.map +1 -0
  43. package/dist/helpers/remove_systemd_service.helper.d.ts +2 -0
  44. package/dist/helpers/remove_systemd_service.helper.d.ts.map +1 -0
  45. package/dist/helpers/remove_systemd_service.helper.js +21 -0
  46. package/dist/helpers/remove_systemd_service.helper.js.map +1 -0
  47. package/dist/helpers/start_systemd_service.helper.d.ts +2 -0
  48. package/dist/helpers/start_systemd_service.helper.d.ts.map +1 -0
  49. package/dist/helpers/start_systemd_service.helper.js +26 -0
  50. package/dist/helpers/start_systemd_service.helper.js.map +1 -0
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +132 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/middleware/auth.middleware.d.ts +3 -0
  56. package/dist/middleware/auth.middleware.d.ts.map +1 -0
  57. package/dist/middleware/auth.middleware.js +7 -0
  58. package/dist/middleware/auth.middleware.js.map +1 -0
  59. package/dist/modules/auth/auth.route.d.ts +3 -0
  60. package/dist/modules/auth/auth.route.d.ts.map +1 -0
  61. package/dist/modules/auth/auth.route.js +16 -0
  62. package/dist/modules/auth/auth.route.js.map +1 -0
  63. package/dist/modules/auth/controllers/auth.controller.d.ts +6 -0
  64. package/dist/modules/auth/controllers/auth.controller.d.ts.map +1 -0
  65. package/dist/modules/auth/controllers/auth.controller.js +123 -0
  66. package/dist/modules/auth/controllers/auth.controller.js.map +1 -0
  67. package/dist/modules/auth/views/login.pug +254 -0
  68. package/dist/modules/auth/views/register.pug +298 -0
  69. package/dist/modules/common/views/404.pug +21 -0
  70. package/dist/modules/dashboard/dashboard.route.d.ts +3 -0
  71. package/dist/modules/dashboard/dashboard.route.d.ts.map +1 -0
  72. package/dist/modules/dashboard/dashboard.route.js +29 -0
  73. package/dist/modules/dashboard/dashboard.route.js.map +1 -0
  74. package/dist/modules/dashboard/views/dash.pug +149 -0
  75. package/dist/modules/dashboard/views/layout.pug +94 -0
  76. package/dist/modules/deployer/controllers/deployer.controller.d.ts +6 -0
  77. package/dist/modules/deployer/controllers/deployer.controller.d.ts.map +1 -0
  78. package/dist/modules/deployer/controllers/deployer.controller.js +119 -0
  79. package/dist/modules/deployer/controllers/deployer.controller.js.map +1 -0
  80. package/dist/modules/deployer/deployer.route.d.ts +3 -0
  81. package/dist/modules/deployer/deployer.route.d.ts.map +1 -0
  82. package/dist/modules/deployer/deployer.route.js +13 -0
  83. package/dist/modules/deployer/deployer.route.js.map +1 -0
  84. package/dist/modules/deployer/helper/deployer.d.ts +9 -0
  85. package/dist/modules/deployer/helper/deployer.d.ts.map +1 -0
  86. package/dist/modules/deployer/helper/deployer.js +89 -0
  87. package/dist/modules/deployer/helper/deployer.js.map +1 -0
  88. package/dist/modules/deployer/views/details.pug +157 -0
  89. package/dist/modules/deployer/views/index.pug +108 -0
  90. package/dist/modules/project/controllers/projects.controller.d.ts +12 -0
  91. package/dist/modules/project/controllers/projects.controller.d.ts.map +1 -0
  92. package/dist/modules/project/controllers/projects.controller.js +267 -0
  93. package/dist/modules/project/controllers/projects.controller.js.map +1 -0
  94. package/dist/modules/project/helper/project_file_sys.helper.d.ts +7 -0
  95. package/dist/modules/project/helper/project_file_sys.helper.d.ts.map +1 -0
  96. package/dist/modules/project/helper/project_file_sys.helper.js +93 -0
  97. package/dist/modules/project/helper/project_file_sys.helper.js.map +1 -0
  98. package/dist/modules/project/project.route.d.ts +3 -0
  99. package/dist/modules/project/project.route.d.ts.map +1 -0
  100. package/dist/modules/project/project.route.js +17 -0
  101. package/dist/modules/project/project.route.js.map +1 -0
  102. package/dist/modules/project/views/create.pug +189 -0
  103. package/dist/modules/project/views/details.pug +238 -0
  104. package/dist/modules/project/views/index.pug +114 -0
  105. package/dist/modules/settings/controllers/setting.controller.d.ts +5 -0
  106. package/dist/modules/settings/controllers/setting.controller.d.ts.map +1 -0
  107. package/dist/modules/settings/controllers/setting.controller.js +193 -0
  108. package/dist/modules/settings/controllers/setting.controller.js.map +1 -0
  109. package/dist/modules/settings/settings.route.d.ts +3 -0
  110. package/dist/modules/settings/settings.route.d.ts.map +1 -0
  111. package/dist/modules/settings/settings.route.js +10 -0
  112. package/dist/modules/settings/settings.route.js.map +1 -0
  113. package/dist/modules/settings/views/index.pug +173 -0
  114. package/dist/modules/webhook/controllers/webhook.controller.d.ts +3 -0
  115. package/dist/modules/webhook/controllers/webhook.controller.d.ts.map +1 -0
  116. package/dist/modules/webhook/controllers/webhook.controller.js +72 -0
  117. package/dist/modules/webhook/controllers/webhook.controller.js.map +1 -0
  118. package/dist/modules/webhook/webhook.route.d.ts +3 -0
  119. package/dist/modules/webhook/webhook.route.d.ts.map +1 -0
  120. package/dist/modules/webhook/webhook.route.js +6 -0
  121. package/dist/modules/webhook/webhook.route.js.map +1 -0
  122. package/dist/utils/app_config.d.ts +3 -0
  123. package/dist/utils/app_config.d.ts.map +1 -0
  124. package/dist/utils/app_config.js +5 -0
  125. package/dist/utils/app_config.js.map +1 -0
  126. package/dist/utils/cli.d.ts +2 -0
  127. package/dist/utils/cli.d.ts.map +1 -0
  128. package/dist/utils/cli.js +68 -0
  129. package/dist/utils/cli.js.map +1 -0
  130. package/package.json +80 -0
  131. package/public/favicon.svg +18 -0
  132. package/public/js/deploy.js +36 -0
  133. package/public/js/deployment-details.js +56 -0
  134. package/public/js/login.js +21 -0
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "vps-deployer",
3
+ "version": "1.0.0",
4
+ "description": "A lightweight, self-hosted continuous deployment (CD) system with a built-in web UI — manages projects on your VPS, accepts GitHub webhooks for automatic deployments, and sends real-time email notifications on deployment events",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "vps-deployer": "dist/index.js"
9
+ },
10
+ "type": "module",
11
+ "files": [
12
+ "dist",
13
+ "public",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "dev": "ts-node src/index.ts ",
19
+ "build": "tsc && find src/modules -type d -name views -exec sh -c 'dest=\"dist/modules/${1#src/modules/}\"; mkdir -p \"$dest\"; cp \"$1\"/* \"$dest/\"' _ {} \\;",
20
+ "start": "node dist/index.js",
21
+ "clean": "rm -rf dist",
22
+ "prepublishOnly": "npm run clean && npm run build"
23
+ },
24
+ "keywords": [
25
+ "self-hosted-cd",
26
+ "continuous-deployment",
27
+ "github-webhooks",
28
+ "auto-deploy",
29
+ "vps-deployment",
30
+ "deployment-automation",
31
+ "ci-cd",
32
+ "lightweight-cli",
33
+ "web-ui",
34
+ "dashboard",
35
+ "webhook-deployer",
36
+ "email-notifications",
37
+ "deployment-notifier",
38
+ "server-management"
39
+ ],
40
+ "author": "0xv1shal",
41
+ "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/0xv1shal/vps-deployer.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/0xv1shal/vps-deployer/issues"
48
+ },
49
+ "homepage": "https://github.com/0xv1shal/vps-deployer#readme",
50
+ "engines": {
51
+ "node": ">=18"
52
+ },
53
+ "os": [
54
+ "linux"
55
+ ],
56
+ "dependencies": {
57
+ "bcrypt": "6.0.0",
58
+ "better-sqlite3": "12.8.0",
59
+ "commander": "14.0.3",
60
+ "dotenv": "17.3.1",
61
+ "express": "5.2.1",
62
+ "express-session": "1.19.0",
63
+ "helmet": "8.1.0",
64
+ "limitngin": "2.0.0",
65
+ "nodemailer": "8.0.4",
66
+ "pug": "3.0.4"
67
+ },
68
+ "devDependencies": {
69
+ "@types/bcrypt": "6.0.0",
70
+ "@types/better-sqlite3": "7.6.13",
71
+ "@types/dotenv": "6.1.1",
72
+ "@types/express": "5.0.6",
73
+ "@types/express-session": "1.18.2",
74
+ "@types/nodemailer": "7.0.11",
75
+ "@types/pug": "2.0.10",
76
+ "nodemon": "3.1.14",
77
+ "ts-node": "10.9.2",
78
+ "typescript": "6.0.2"
79
+ }
80
+ }
@@ -0,0 +1,18 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
2
+ <!-- Icon bg -->
3
+ <rect width="250" height="250" rx="52" fill="#060d1a"/>
4
+
5
+ <!-- Three arcs -->
6
+ <path d="M 125,35 A 90,90 0 0,1 203,170" fill="none" stroke="#60a5fa" stroke-width="14" stroke-linecap="round"/>
7
+ <path d="M 203,170 A 90,90 0 0,1 47,170" fill="none" stroke="#2563eb" stroke-width="14" stroke-linecap="round"/>
8
+ <path d="M 47,170 A 90,90 0 0,1 125,35" fill="none" stroke="#1d4ed8" stroke-width="14" stroke-linecap="round"/>
9
+
10
+ <!-- Gap punches -->
11
+ <circle cx="125" cy="35" r="9" fill="#060d1a"/>
12
+ <circle cx="203" cy="170" r="9" fill="#060d1a"/>
13
+ <circle cx="47" cy="170" r="9" fill="#060d1a"/>
14
+
15
+ <!-- Center anchor -->
16
+ <circle cx="125" cy="125" r="14" fill="#60a5fa"/>
17
+ <circle cx="125" cy="125" r="6" fill="#060d1a"/>
18
+ </svg>
@@ -0,0 +1,36 @@
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+ const btn = document.getElementById("deploy-btn");
3
+
4
+ if (!btn) return;
5
+
6
+ btn.addEventListener("click", async () => {
7
+ const projId = btn.dataset.projid;
8
+
9
+ btn.disabled = true;
10
+ btn.innerText = "Deploying...";
11
+
12
+ try {
13
+ const res = await fetch("/deploy", {
14
+ method: "POST",
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ },
18
+ body: JSON.stringify({ projId }),
19
+ });
20
+
21
+ const data = await res.json();
22
+
23
+ if (!res.ok) {
24
+ alert(data.message || "Failed");
25
+ btn.disabled = false;
26
+ btn.innerText = "🚀 Deploy Now";
27
+ return;
28
+ }
29
+
30
+ window.location.href = `/deployment/${data.deployId}`;
31
+ } catch {
32
+ btn.disabled = false;
33
+ btn.innerText = "🚀 Deploy Now";
34
+ }
35
+ });
36
+ });
@@ -0,0 +1,56 @@
1
+ const deployId = document.getElementById("deploy-id").dataset.id;
2
+
3
+ function badge(status) {
4
+ if (status === "success") return "badge bg-success";
5
+ if (status === "failed") return "badge bg-danger";
6
+ return "badge bg-warning text-dark";
7
+ }
8
+
9
+ async function fetchUpdates() {
10
+ try {
11
+ const res = await fetch(`/deploy/${deployId}`);
12
+ const data = await res.json();
13
+
14
+ // update status
15
+ const statusEl = document.getElementById("deploy-status");
16
+ statusEl.innerHTML = `<span class="${badge(data.deployment.status)}">${data.deployment.status}</span>`;
17
+
18
+ // update finished time
19
+ document.getElementById("finished-at").innerText =
20
+ data.deployment.finished_at || "Running...";
21
+
22
+ // update logs
23
+ const logsContainer = document.getElementById("logs");
24
+ logsContainer.innerHTML = "";
25
+
26
+ data.logs.forEach(log => {
27
+ const div = document.createElement("div");
28
+ div.className = "card mb-3";
29
+
30
+ div.innerHTML = `
31
+ <div class="card-header">
32
+ <strong>${log.cmd}</strong>
33
+ <span class="float-end ${badge(log.status)}">${log.status}</span>
34
+ </div>
35
+ <div class="card-body">
36
+ <small class="text-muted">
37
+ Started: ${log.started_at}<br/>
38
+ Finished: ${log.finished_at || "Running..."}
39
+ </small>
40
+ <pre class="bg-dark text-success p-2 mt-2" style="max-height:300px; overflow:auto;">${log.log || ""}</pre>
41
+ </div>
42
+ `;
43
+
44
+ logsContainer.appendChild(div);
45
+ });
46
+
47
+ if (data.deployment.status !== "running") {
48
+ clearInterval(interval);
49
+ }
50
+
51
+ } catch (err) {
52
+ console.error(err);
53
+ }
54
+ }
55
+
56
+ const interval = setInterval(fetchUpdates, 3000);
@@ -0,0 +1,21 @@
1
+ // Password visibility toggle
2
+ const toggleBtn = document.getElementById('togglePassword');
3
+ const passwordField = document.getElementById('password');
4
+
5
+ if (toggleBtn && passwordField) {
6
+ toggleBtn.addEventListener('click', function() {
7
+ const type = passwordField.getAttribute('type') === 'password' ? 'text' : 'password';
8
+ passwordField.setAttribute('type', type);
9
+ const icon = this.querySelector('i');
10
+ icon.classList.toggle('bi-eye');
11
+ icon.classList.toggle('bi-eye-slash');
12
+ });
13
+ }
14
+
15
+ // Auto-dismiss alerts after 5 seconds
16
+ document.querySelectorAll('.alert').forEach(alert => {
17
+ setTimeout(() => {
18
+ const bsAlert = new bootstrap.Alert(alert);
19
+ bsAlert.close();
20
+ }, 5000);
21
+ });