hostfn 0.1.1 → 0.1.2

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 (179) hide show
  1. package/dist/__tests__/core/backup.test.d.ts +2 -0
  2. package/dist/__tests__/core/backup.test.d.ts.map +1 -0
  3. package/dist/__tests__/core/backup.test.js +108 -0
  4. package/dist/__tests__/core/backup.test.js.map +1 -0
  5. package/dist/__tests__/core/health.test.d.ts +2 -0
  6. package/dist/__tests__/core/health.test.d.ts.map +1 -0
  7. package/dist/__tests__/core/health.test.js +97 -0
  8. package/dist/__tests__/core/health.test.js.map +1 -0
  9. package/dist/__tests__/core/lock.test.d.ts +2 -0
  10. package/dist/__tests__/core/lock.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/lock.test.js +136 -0
  12. package/dist/__tests__/core/lock.test.js.map +1 -0
  13. package/dist/__tests__/core/nginx-multi-domain.test.d.ts +2 -0
  14. package/dist/__tests__/core/nginx-multi-domain.test.d.ts.map +1 -0
  15. package/dist/__tests__/core/nginx-multi-domain.test.js +158 -0
  16. package/dist/__tests__/core/nginx-multi-domain.test.js.map +1 -0
  17. package/dist/__tests__/runtimes/pm2.test.d.ts +2 -0
  18. package/dist/__tests__/runtimes/pm2.test.d.ts.map +1 -0
  19. package/dist/__tests__/runtimes/pm2.test.js +111 -0
  20. package/dist/__tests__/runtimes/pm2.test.js.map +1 -0
  21. package/dist/__tests__/utils/validation.test.d.ts +2 -0
  22. package/dist/__tests__/utils/validation.test.d.ts.map +1 -0
  23. package/dist/__tests__/utils/validation.test.js +136 -0
  24. package/dist/__tests__/utils/validation.test.js.map +1 -0
  25. package/dist/commands/deploy.d.ts +11 -0
  26. package/dist/commands/deploy.d.ts.map +1 -0
  27. package/dist/commands/deploy.js +636 -0
  28. package/dist/commands/deploy.js.map +1 -0
  29. package/dist/commands/env.d.ts +21 -0
  30. package/dist/commands/env.d.ts.map +1 -0
  31. package/dist/commands/env.js +317 -0
  32. package/dist/commands/env.js.map +1 -0
  33. package/dist/commands/expose.d.ts +6 -0
  34. package/dist/commands/expose.d.ts.map +1 -0
  35. package/dist/commands/expose.js +379 -0
  36. package/dist/commands/expose.js.map +1 -0
  37. package/dist/commands/init.d.ts +2 -0
  38. package/dist/commands/init.d.ts.map +1 -0
  39. package/dist/commands/init.js +175 -0
  40. package/dist/commands/init.js.map +1 -0
  41. package/dist/commands/logs.d.ts +10 -0
  42. package/dist/commands/logs.d.ts.map +1 -0
  43. package/dist/commands/logs.js +75 -0
  44. package/dist/commands/logs.js.map +1 -0
  45. package/dist/commands/rollback.d.ts +6 -0
  46. package/dist/commands/rollback.d.ts.map +1 -0
  47. package/dist/commands/rollback.js +113 -0
  48. package/dist/commands/rollback.js.map +1 -0
  49. package/dist/commands/server/info.d.ts +2 -0
  50. package/dist/commands/server/info.d.ts.map +1 -0
  51. package/dist/commands/server/info.js +104 -0
  52. package/dist/commands/server/info.js.map +1 -0
  53. package/dist/commands/server/setup.d.ts +11 -0
  54. package/dist/commands/server/setup.d.ts.map +1 -0
  55. package/dist/commands/server/setup.js +161 -0
  56. package/dist/commands/server/setup.js.map +1 -0
  57. package/dist/commands/status.d.ts +6 -0
  58. package/dist/commands/status.d.ts.map +1 -0
  59. package/dist/commands/status.js +120 -0
  60. package/dist/commands/status.js.map +1 -0
  61. package/dist/config/loader.d.ts +21 -0
  62. package/dist/config/loader.d.ts.map +1 -0
  63. package/dist/config/loader.js +54 -0
  64. package/dist/config/loader.js.map +1 -0
  65. package/dist/config/schema.d.ts +323 -0
  66. package/dist/config/schema.d.ts.map +1 -0
  67. package/dist/config/schema.js +108 -0
  68. package/dist/config/schema.js.map +1 -0
  69. package/dist/core/backup.d.ts +34 -0
  70. package/dist/core/backup.d.ts.map +1 -0
  71. package/dist/core/backup.js +95 -0
  72. package/dist/core/backup.js.map +1 -0
  73. package/dist/core/health.d.ts +31 -0
  74. package/dist/core/health.d.ts.map +1 -0
  75. package/dist/core/health.js +78 -0
  76. package/dist/core/health.js.map +1 -0
  77. package/dist/core/local.d.ts +19 -0
  78. package/dist/core/local.d.ts.map +1 -0
  79. package/dist/core/local.js +50 -0
  80. package/dist/core/local.js.map +1 -0
  81. package/dist/core/lock.d.ts +28 -0
  82. package/dist/core/lock.d.ts.map +1 -0
  83. package/dist/core/lock.js +89 -0
  84. package/dist/core/lock.js.map +1 -0
  85. package/dist/core/nginx.d.ts +43 -0
  86. package/dist/core/nginx.d.ts.map +1 -0
  87. package/dist/core/nginx.js +131 -0
  88. package/dist/core/nginx.js.map +1 -0
  89. package/dist/core/ssh.d.ts +79 -0
  90. package/dist/core/ssh.d.ts.map +1 -0
  91. package/dist/core/ssh.js +264 -0
  92. package/dist/core/ssh.js.map +1 -0
  93. package/dist/core/sync.d.ts +25 -0
  94. package/dist/core/sync.d.ts.map +1 -0
  95. package/dist/core/sync.js +117 -0
  96. package/dist/core/sync.js.map +1 -0
  97. package/dist/core/workspace.d.ts +13 -0
  98. package/dist/core/workspace.d.ts.map +1 -0
  99. package/dist/core/workspace.js +141 -0
  100. package/dist/core/workspace.js.map +1 -0
  101. package/dist/index.d.ts +3 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +232 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/runtimes/base.d.ts +115 -0
  106. package/dist/runtimes/base.d.ts.map +1 -0
  107. package/dist/runtimes/base.js +16 -0
  108. package/dist/runtimes/base.js.map +1 -0
  109. package/dist/runtimes/nodejs/detector.d.ts +47 -0
  110. package/dist/runtimes/nodejs/detector.d.ts.map +1 -0
  111. package/dist/runtimes/nodejs/detector.js +143 -0
  112. package/dist/runtimes/nodejs/detector.js.map +1 -0
  113. package/dist/runtimes/nodejs/index.d.ts +14 -0
  114. package/dist/runtimes/nodejs/index.d.ts.map +1 -0
  115. package/dist/runtimes/nodejs/index.js +213 -0
  116. package/dist/runtimes/nodejs/index.js.map +1 -0
  117. package/dist/runtimes/nodejs/pm2.d.ts +17 -0
  118. package/dist/runtimes/nodejs/pm2.d.ts.map +1 -0
  119. package/dist/runtimes/nodejs/pm2.js +60 -0
  120. package/dist/runtimes/nodejs/pm2.js.map +1 -0
  121. package/dist/runtimes/registry.d.ts +34 -0
  122. package/dist/runtimes/registry.d.ts.map +1 -0
  123. package/dist/runtimes/registry.js +58 -0
  124. package/dist/runtimes/registry.js.map +1 -0
  125. package/dist/utils/logger.d.ts +47 -0
  126. package/dist/utils/logger.d.ts.map +1 -0
  127. package/dist/utils/logger.js +76 -0
  128. package/dist/utils/logger.js.map +1 -0
  129. package/dist/utils/validation.d.ts +32 -0
  130. package/dist/utils/validation.d.ts.map +1 -0
  131. package/dist/utils/validation.js +125 -0
  132. package/dist/utils/validation.js.map +1 -0
  133. package/package.json +33 -16
  134. package/LICENSE +0 -21
  135. package/README.md +0 -1136
  136. package/_conduct/specs/1.v0.spec.md +0 -1041
  137. package/examples/express-api/package.json +0 -22
  138. package/examples/express-api/src/index.ts +0 -16
  139. package/examples/express-api/tsconfig.json +0 -11
  140. package/examples/github-actions-deploy.yml +0 -40
  141. package/examples/monorepo-config.json +0 -76
  142. package/examples/monorepo-multi-server-config.json +0 -74
  143. package/packages/cli/package.json +0 -40
  144. package/turbo.json +0 -24
  145. /package/{packages/cli/src → src}/__tests__/core/backup.test.ts +0 -0
  146. /package/{packages/cli/src → src}/__tests__/core/health.test.ts +0 -0
  147. /package/{packages/cli/src → src}/__tests__/core/lock.test.ts +0 -0
  148. /package/{packages/cli/src → src}/__tests__/core/nginx-multi-domain.test.ts +0 -0
  149. /package/{packages/cli/src → src}/__tests__/runtimes/pm2.test.ts +0 -0
  150. /package/{packages/cli/src → src}/__tests__/utils/validation.test.ts +0 -0
  151. /package/{packages/cli/src → src}/commands/deploy.ts +0 -0
  152. /package/{packages/cli/src → src}/commands/env.ts +0 -0
  153. /package/{packages/cli/src → src}/commands/expose.ts +0 -0
  154. /package/{packages/cli/src → src}/commands/init.ts +0 -0
  155. /package/{packages/cli/src → src}/commands/logs.ts +0 -0
  156. /package/{packages/cli/src → src}/commands/rollback.ts +0 -0
  157. /package/{packages/cli/src → src}/commands/server/info.ts +0 -0
  158. /package/{packages/cli/src → src}/commands/server/setup.ts +0 -0
  159. /package/{packages/cli/src → src}/commands/status.ts +0 -0
  160. /package/{packages/cli/src → src}/config/loader.ts +0 -0
  161. /package/{packages/cli/src → src}/config/schema.ts +0 -0
  162. /package/{packages/cli/src → src}/core/backup.ts +0 -0
  163. /package/{packages/cli/src → src}/core/health.ts +0 -0
  164. /package/{packages/cli/src → src}/core/local.ts +0 -0
  165. /package/{packages/cli/src → src}/core/lock.ts +0 -0
  166. /package/{packages/cli/src → src}/core/nginx.ts +0 -0
  167. /package/{packages/cli/src → src}/core/ssh.ts +0 -0
  168. /package/{packages/cli/src → src}/core/sync.ts +0 -0
  169. /package/{packages/cli/src → src}/core/workspace.ts +0 -0
  170. /package/{packages/cli/src → src}/index.ts +0 -0
  171. /package/{packages/cli/src → src}/runtimes/base.ts +0 -0
  172. /package/{packages/cli/src → src}/runtimes/nodejs/detector.ts +0 -0
  173. /package/{packages/cli/src → src}/runtimes/nodejs/index.ts +0 -0
  174. /package/{packages/cli/src → src}/runtimes/nodejs/pm2.ts +0 -0
  175. /package/{packages/cli/src → src}/runtimes/registry.ts +0 -0
  176. /package/{packages/cli/src → src}/utils/logger.ts +0 -0
  177. /package/{packages/cli/src → src}/utils/validation.ts +0 -0
  178. /package/{packages/cli/tsconfig.json → tsconfig.json} +0 -0
  179. /package/{packages/cli/vitest.config.ts → vitest.config.ts} +0 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/backup.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,108 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { BackupManager } from '../../core/backup.js';
3
+ // Mock SSH connection
4
+ const mockSSH = {
5
+ exec: vi.fn(),
6
+ exists: vi.fn(),
7
+ mkdir: vi.fn(),
8
+ upload: vi.fn(),
9
+ download: vi.fn(),
10
+ disconnect: vi.fn(),
11
+ };
12
+ describe('BackupManager', () => {
13
+ let backupManager;
14
+ beforeEach(() => {
15
+ vi.clearAllMocks();
16
+ backupManager = new BackupManager(mockSSH, '/var/www/myapp');
17
+ });
18
+ describe('create', () => {
19
+ it('should create backup with timestamp', async () => {
20
+ mockSSH.mkdir.mockResolvedValue(undefined);
21
+ mockSSH.exists.mockResolvedValue(true); // dist exists
22
+ mockSSH.exec.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 });
23
+ const backupPath = await backupManager.create();
24
+ expect(backupPath).toMatch(/\/var\/www\/myapp\/backups\/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/);
25
+ expect(mockSSH.mkdir).toHaveBeenCalled();
26
+ expect(mockSSH.exec).toHaveBeenCalled();
27
+ });
28
+ it('should return path even if source directory does not exist', async () => {
29
+ mockSSH.mkdir.mockResolvedValue(undefined);
30
+ mockSSH.exists.mockResolvedValue(false); // No dist directory
31
+ const backupPath = await backupManager.create();
32
+ // Returns backup path but doesn't fail
33
+ expect(backupPath).toMatch(/\/var\/www\/myapp\/backups\/\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}/);
34
+ expect(mockSSH.mkdir).toHaveBeenCalled();
35
+ });
36
+ });
37
+ describe('list', () => {
38
+ it('should list all backups with timestamps', async () => {
39
+ mockSSH.exists.mockResolvedValue(true);
40
+ mockSSH.exec.mockResolvedValue({
41
+ stdout: 'myapp.backup.20251114_130000\nmyapp.backup.20251114_120000\n', // sorted reverse
42
+ stderr: '',
43
+ exitCode: 0
44
+ });
45
+ const backups = await backupManager.list();
46
+ expect(backups).toHaveLength(2);
47
+ expect(backups[0]).toContain('20251114_130000'); // Most recent first
48
+ expect(backups[1]).toContain('20251114_120000');
49
+ });
50
+ it('should return empty array when no backups exist', async () => {
51
+ mockSSH.exec.mockResolvedValue({
52
+ stdout: '',
53
+ stderr: '',
54
+ exitCode: 0
55
+ });
56
+ const backups = await backupManager.list();
57
+ expect(backups).toHaveLength(0);
58
+ });
59
+ });
60
+ describe('restore', () => {
61
+ it('should restore from backup', async () => {
62
+ mockSSH.exists.mockResolvedValue(true);
63
+ mockSSH.exec.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 });
64
+ await backupManager.restore('myapp.backup.20251114_120000');
65
+ expect(mockSSH.exec).toHaveBeenCalledWith(expect.stringContaining('cp -r'));
66
+ });
67
+ });
68
+ describe('cleanup', () => {
69
+ it('should keep only specified number of backups', async () => {
70
+ const backupNames = [
71
+ 'myapp.backup.20251114_150000', // Most recent (sorted)
72
+ 'myapp.backup.20251114_140000',
73
+ 'myapp.backup.20251114_130000',
74
+ 'myapp.backup.20251114_120000',
75
+ 'myapp.backup.20251114_110000',
76
+ 'myapp.backup.20251114_100000', // Oldest
77
+ ];
78
+ mockSSH.exists.mockResolvedValue(true);
79
+ mockSSH.exec
80
+ .mockResolvedValueOnce({
81
+ stdout: backupNames.join('\n'),
82
+ stderr: '',
83
+ exitCode: 0
84
+ })
85
+ .mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 });
86
+ await backupManager.cleanup(3);
87
+ // Should remove oldest 3 backups
88
+ expect(mockSSH.exec).toHaveBeenCalledWith(expect.stringContaining('rm -rf'));
89
+ });
90
+ it('should not remove backups if under limit', async () => {
91
+ const backupNames = [
92
+ 'myapp.backup.20251114_100000',
93
+ 'myapp.backup.20251114_110000',
94
+ ];
95
+ mockSSH.exists.mockResolvedValue(true);
96
+ mockSSH.exec.mockResolvedValueOnce({
97
+ stdout: backupNames.join('\n'),
98
+ stderr: '',
99
+ exitCode: 0
100
+ });
101
+ await backupManager.cleanup(5);
102
+ // Should only call list, not remove (called twice: exists + ls)
103
+ expect(mockSSH.exec).toHaveBeenCalledTimes(1);
104
+ expect(mockSSH.exec).toHaveBeenCalledWith(expect.stringContaining('ls -1'));
105
+ });
106
+ });
107
+ });
108
+ //# sourceMappingURL=backup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/backup.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=health.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/health.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { HealthCheck } from '../../core/health.js';
3
+ // Mock fetch globally
4
+ global.fetch = vi.fn();
5
+ describe('HealthCheck', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ describe('check', () => {
10
+ it('should return healthy for successful response', async () => {
11
+ global.fetch.mockResolvedValueOnce({
12
+ ok: true,
13
+ status: 200,
14
+ });
15
+ const result = await HealthCheck.check({
16
+ url: 'http://localhost:3000/health',
17
+ });
18
+ expect(result.healthy).toBe(true);
19
+ expect(result.statusCode).toBe(200);
20
+ expect(result.responseTime).toBeGreaterThanOrEqual(0);
21
+ });
22
+ it('should return unhealthy for failed response', async () => {
23
+ global.fetch.mockResolvedValueOnce({
24
+ ok: false,
25
+ status: 500,
26
+ });
27
+ const result = await HealthCheck.check({
28
+ url: 'http://localhost:3000/health',
29
+ });
30
+ expect(result.healthy).toBe(false);
31
+ expect(result.statusCode).toBe(500);
32
+ });
33
+ it('should return unhealthy for network error', async () => {
34
+ global.fetch.mockRejectedValueOnce(new Error('Network error'));
35
+ const result = await HealthCheck.check({
36
+ url: 'http://localhost:3000/health',
37
+ });
38
+ expect(result.healthy).toBe(false);
39
+ expect(result.error).toBeDefined();
40
+ });
41
+ it('should respect timeout', async () => {
42
+ global.fetch.mockImplementationOnce(() => new Promise((resolve) => setTimeout(resolve, 2000)));
43
+ const result = await HealthCheck.check({
44
+ url: 'http://localhost:3000/health',
45
+ timeout: 100,
46
+ });
47
+ expect(result.healthy).toBe(false);
48
+ });
49
+ });
50
+ describe('waitForReady', () => {
51
+ it('should return true when service becomes healthy', async () => {
52
+ let callCount = 0;
53
+ global.fetch.mockImplementation(() => {
54
+ callCount++;
55
+ return Promise.resolve({
56
+ ok: callCount >= 2, // Becomes healthy on second call
57
+ status: callCount >= 2 ? 200 : 503,
58
+ });
59
+ });
60
+ const result = await HealthCheck.waitForReady({
61
+ url: 'http://localhost:3000/health',
62
+ retries: 5,
63
+ interval: 10,
64
+ });
65
+ expect(result).toBe(true);
66
+ expect(callCount).toBeGreaterThanOrEqual(2);
67
+ });
68
+ it('should return false when max retries exceeded', async () => {
69
+ global.fetch.mockResolvedValue({
70
+ ok: false,
71
+ status: 503,
72
+ });
73
+ const result = await HealthCheck.waitForReady({
74
+ url: 'http://localhost:3000/health',
75
+ retries: 2,
76
+ interval: 10,
77
+ });
78
+ expect(result).toBe(false);
79
+ });
80
+ it('should call progress callback on each attempt', async () => {
81
+ global.fetch.mockResolvedValue({
82
+ ok: false,
83
+ status: 503,
84
+ });
85
+ const progressCalls = [];
86
+ await HealthCheck.waitForReady({
87
+ url: 'http://localhost:3000/health',
88
+ retries: 3,
89
+ interval: 10,
90
+ }, (attempt) => {
91
+ progressCalls.push(attempt);
92
+ });
93
+ expect(progressCalls).toEqual([1, 2, 3]);
94
+ });
95
+ });
96
+ });
97
+ //# sourceMappingURL=health.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/health.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lock.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/lock.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { LockManager } from '../../core/lock.js';
3
+ // Mock SSH connection
4
+ const mockSSH = {
5
+ exec: vi.fn(),
6
+ exists: vi.fn(),
7
+ mkdir: vi.fn(),
8
+ upload: vi.fn(),
9
+ download: vi.fn(),
10
+ disconnect: vi.fn(),
11
+ };
12
+ // Mock Logger to prevent console output
13
+ vi.mock('../../utils/logger.js', () => ({
14
+ Logger: {
15
+ error: vi.fn(),
16
+ warn: vi.fn(),
17
+ info: vi.fn(),
18
+ log: vi.fn(),
19
+ br: vi.fn(),
20
+ },
21
+ }));
22
+ describe('LockManager', () => {
23
+ let lockManager;
24
+ beforeEach(() => {
25
+ vi.clearAllMocks();
26
+ lockManager = new LockManager(mockSSH, '/var/www/myapp');
27
+ });
28
+ describe('acquire', () => {
29
+ it('should acquire lock when no lock exists', async () => {
30
+ mockSSH.exists.mockResolvedValue(false);
31
+ mockSSH.exec.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 });
32
+ const acquired = await lockManager.acquire();
33
+ expect(acquired).toBe(true);
34
+ expect(mockSSH.exec).toHaveBeenCalledWith(expect.stringContaining('.hostfn-deploy.lock'));
35
+ });
36
+ it('should fail when valid lock exists', async () => {
37
+ const recentLock = {
38
+ pid: 12345,
39
+ user: 'developer',
40
+ timestamp: Date.now() - 60000, // 1 minute ago
41
+ hostname: 'laptop',
42
+ };
43
+ mockSSH.exists.mockResolvedValue(true);
44
+ mockSSH.exec.mockResolvedValue({
45
+ stdout: JSON.stringify(recentLock),
46
+ stderr: '',
47
+ exitCode: 0
48
+ });
49
+ const acquired = await lockManager.acquire();
50
+ expect(acquired).toBe(false);
51
+ });
52
+ it('should acquire lock when stale lock exists', async () => {
53
+ const staleLock = {
54
+ pid: 12345,
55
+ user: 'developer',
56
+ timestamp: Date.now() - 400000, // 6+ minutes ago (stale)
57
+ hostname: 'laptop',
58
+ };
59
+ mockSSH.exists.mockResolvedValue(true);
60
+ mockSSH.exec
61
+ .mockResolvedValueOnce({
62
+ stdout: JSON.stringify(staleLock),
63
+ stderr: '',
64
+ exitCode: 0
65
+ })
66
+ .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 }) // release
67
+ .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 }); // acquire
68
+ const acquired = await lockManager.acquire();
69
+ expect(acquired).toBe(true);
70
+ });
71
+ it('should acquire lock when invalid lock file exists', async () => {
72
+ mockSSH.exists.mockResolvedValue(true);
73
+ mockSSH.exec
74
+ .mockResolvedValueOnce({
75
+ stdout: 'invalid json',
76
+ stderr: '',
77
+ exitCode: 0
78
+ })
79
+ .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 }) // release
80
+ .mockResolvedValueOnce({ stdout: '', stderr: '', exitCode: 0 }); // acquire
81
+ const acquired = await lockManager.acquire();
82
+ expect(acquired).toBe(true);
83
+ });
84
+ });
85
+ describe('release', () => {
86
+ it('should remove lock file', async () => {
87
+ mockSSH.exec.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 });
88
+ await lockManager.release();
89
+ expect(mockSSH.exec).toHaveBeenCalledWith(expect.stringContaining('rm -f'));
90
+ });
91
+ it('should not throw on release error', async () => {
92
+ mockSSH.exec.mockRejectedValue(new Error('File not found'));
93
+ await expect(lockManager.release()).resolves.not.toThrow();
94
+ });
95
+ });
96
+ describe('isLocked', () => {
97
+ it('should return false when no lock exists', async () => {
98
+ mockSSH.exists.mockResolvedValue(false);
99
+ const locked = await lockManager.isLocked();
100
+ expect(locked).toBe(false);
101
+ });
102
+ it('should return true when valid lock exists', async () => {
103
+ const recentLock = {
104
+ pid: 12345,
105
+ user: 'developer',
106
+ timestamp: Date.now() - 60000, // 1 minute ago
107
+ hostname: 'laptop',
108
+ };
109
+ mockSSH.exists.mockResolvedValue(true);
110
+ mockSSH.exec.mockResolvedValue({
111
+ stdout: JSON.stringify(recentLock),
112
+ stderr: '',
113
+ exitCode: 0
114
+ });
115
+ const locked = await lockManager.isLocked();
116
+ expect(locked).toBe(true);
117
+ });
118
+ it('should return false when stale lock exists', async () => {
119
+ const staleLock = {
120
+ pid: 12345,
121
+ user: 'developer',
122
+ timestamp: Date.now() - 400000, // 6+ minutes ago (stale)
123
+ hostname: 'laptop',
124
+ };
125
+ mockSSH.exists.mockResolvedValue(true);
126
+ mockSSH.exec.mockResolvedValue({
127
+ stdout: JSON.stringify(staleLock),
128
+ stderr: '',
129
+ exitCode: 0
130
+ });
131
+ const locked = await lockManager.isLocked();
132
+ expect(locked).toBe(false);
133
+ });
134
+ });
135
+ });
136
+ //# sourceMappingURL=lock.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/lock.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=nginx-multi-domain.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nginx-multi-domain.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/nginx-multi-domain.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,158 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { NginxConfigGenerator } from '../../core/nginx.js';
3
+ describe('NginxConfigGenerator - Multi-Domain Support', () => {
4
+ describe('generate with single domain (backward compatibility)', () => {
5
+ it('should generate config with single domain string', () => {
6
+ const config = NginxConfigGenerator.generate({
7
+ domain: 'example.com',
8
+ ssl: false,
9
+ services: [
10
+ {
11
+ name: 'test-app',
12
+ port: 3000,
13
+ isDefault: true,
14
+ },
15
+ ],
16
+ environment: 'production',
17
+ });
18
+ expect(config).toContain('server_name example.com;');
19
+ expect(config).toContain('proxy_pass http://localhost:3000;');
20
+ });
21
+ it('should generate SSL config with single domain', () => {
22
+ const config = NginxConfigGenerator.generate({
23
+ domain: 'example.com',
24
+ ssl: true,
25
+ services: [
26
+ {
27
+ name: 'test-app',
28
+ port: 3000,
29
+ isDefault: true,
30
+ },
31
+ ],
32
+ environment: 'production',
33
+ });
34
+ expect(config).toContain('server_name example.com;');
35
+ expect(config).toContain('listen 443 ssl http2;');
36
+ expect(config).toContain('ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;');
37
+ expect(config).toContain('ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;');
38
+ });
39
+ });
40
+ describe('generate with multiple domains', () => {
41
+ it('should generate config with multiple domains in server_name', () => {
42
+ const config = NginxConfigGenerator.generate({
43
+ domain: ['example.com', 'www.example.com', 'app.example.com'],
44
+ ssl: false,
45
+ services: [
46
+ {
47
+ name: 'test-app',
48
+ port: 3000,
49
+ isDefault: true,
50
+ },
51
+ ],
52
+ environment: 'production',
53
+ });
54
+ expect(config).toContain('server_name example.com www.example.com app.example.com;');
55
+ expect(config).toContain('proxy_pass http://localhost:3000;');
56
+ });
57
+ it('should use primary domain for SSL certificate paths', () => {
58
+ const config = NginxConfigGenerator.generate({
59
+ domain: ['example.com', 'www.example.com', 'api.example.com'],
60
+ ssl: true,
61
+ services: [
62
+ {
63
+ name: 'test-app',
64
+ port: 3000,
65
+ isDefault: true,
66
+ },
67
+ ],
68
+ environment: 'production',
69
+ });
70
+ // Should have all domains in server_name
71
+ expect(config).toContain('server_name example.com www.example.com api.example.com;');
72
+ // Should use first domain (primary) for certificate paths
73
+ expect(config).toContain('ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;');
74
+ expect(config).toContain('ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;');
75
+ // Should NOT use other domains for cert paths
76
+ expect(config).not.toContain('ssl_certificate /etc/letsencrypt/live/www.example.com/');
77
+ expect(config).not.toContain('ssl_certificate /etc/letsencrypt/live/api.example.com/');
78
+ });
79
+ it('should generate HTTP redirect block for all domains', () => {
80
+ const config = NginxConfigGenerator.generate({
81
+ domain: ['example.com', 'www.example.com'],
82
+ ssl: true,
83
+ services: [
84
+ {
85
+ name: 'test-app',
86
+ port: 3000,
87
+ isDefault: true,
88
+ },
89
+ ],
90
+ environment: 'production',
91
+ });
92
+ // Should have redirect block
93
+ expect(config).toContain('return 301 https://$host$request_uri;');
94
+ // Should have two server blocks (HTTPS + redirect)
95
+ const serverBlocks = config.match(/server \{/g);
96
+ expect(serverBlocks).toHaveLength(2);
97
+ });
98
+ });
99
+ describe('generate without domain', () => {
100
+ it('should use catch-all server_name when no domain provided', () => {
101
+ const config = NginxConfigGenerator.generate({
102
+ ssl: false,
103
+ services: [
104
+ {
105
+ name: 'test-app',
106
+ port: 3000,
107
+ isDefault: true,
108
+ },
109
+ ],
110
+ environment: 'production',
111
+ });
112
+ expect(config).toContain('server_name _;');
113
+ });
114
+ it('should use catch-all server_name with empty array', () => {
115
+ const config = NginxConfigGenerator.generate({
116
+ domain: [],
117
+ ssl: false,
118
+ services: [
119
+ {
120
+ name: 'test-app',
121
+ port: 3000,
122
+ isDefault: true,
123
+ },
124
+ ],
125
+ environment: 'production',
126
+ });
127
+ expect(config).toContain('server_name _;');
128
+ });
129
+ });
130
+ describe('generate with multiple services and multiple domains', () => {
131
+ it('should handle path-based routing with multiple domains', () => {
132
+ const config = NginxConfigGenerator.generate({
133
+ domain: ['example.com', 'www.example.com'],
134
+ ssl: false,
135
+ services: [
136
+ {
137
+ name: 'api-service',
138
+ port: 3001,
139
+ exposePath: '/api',
140
+ isDefault: false,
141
+ },
142
+ {
143
+ name: 'web-service',
144
+ port: 3000,
145
+ isDefault: true,
146
+ },
147
+ ],
148
+ environment: 'production',
149
+ });
150
+ expect(config).toContain('server_name example.com www.example.com;');
151
+ expect(config).toContain('location /api {');
152
+ expect(config).toContain('proxy_pass http://localhost:3001;');
153
+ expect(config).toContain('location / {');
154
+ expect(config).toContain('proxy_pass http://localhost:3000;');
155
+ });
156
+ });
157
+ });
158
+ //# sourceMappingURL=nginx-multi-domain.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nginx-multi-domain.test.js","sourceRoot":"","sources":["../../../src/__tests__/core/nginx-multi-domain.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pm2.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pm2.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/runtimes/pm2.test.ts"],"names":[],"mappings":""}