projax 3.3.40 → 3.3.51

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 (115) hide show
  1. package/README.md +73 -0
  2. package/dist/__tests__/port-scanner.test.js +7 -17
  3. package/dist/__tests__/script-runner.test.js +7 -17
  4. package/dist/api/__tests__/database.test.js +7 -17
  5. package/dist/api/__tests__/database.test.js.map +1 -1
  6. package/dist/api/__tests__/routes.test.js +7 -17
  7. package/dist/api/__tests__/routes.test.js.map +1 -1
  8. package/dist/api/__tests__/scanner.test.js +7 -17
  9. package/dist/api/__tests__/scanner.test.js.map +1 -1
  10. package/dist/api/database.d.ts +20 -1
  11. package/dist/api/database.d.ts.map +1 -1
  12. package/dist/api/database.js +192 -21
  13. package/dist/api/database.js.map +1 -1
  14. package/dist/api/index.d.ts.map +1 -1
  15. package/dist/api/index.js +17 -19
  16. package/dist/api/index.js.map +1 -1
  17. package/dist/api/migrate.js +2 -1
  18. package/dist/api/migrate.js.map +1 -1
  19. package/dist/api/package.json +3 -2
  20. package/dist/api/routes/backup.d.ts +3 -0
  21. package/dist/api/routes/backup.d.ts.map +1 -0
  22. package/dist/api/routes/backup.js +51 -0
  23. package/dist/api/routes/backup.js.map +1 -0
  24. package/dist/api/routes/index.d.ts.map +1 -1
  25. package/dist/api/routes/index.js +6 -0
  26. package/dist/api/routes/index.js.map +1 -1
  27. package/dist/api/routes/mcp.d.ts +3 -0
  28. package/dist/api/routes/mcp.d.ts.map +1 -0
  29. package/dist/api/routes/mcp.js +147 -0
  30. package/dist/api/routes/mcp.js.map +1 -0
  31. package/dist/api/routes/projects.d.ts.map +1 -1
  32. package/dist/api/routes/projects.js +27 -17
  33. package/dist/api/routes/projects.js.map +1 -1
  34. package/dist/api/routes/settings.d.ts.map +1 -1
  35. package/dist/api/routes/settings.js +119 -11
  36. package/dist/api/routes/settings.js.map +1 -1
  37. package/dist/api/routes/workspaces.d.ts +3 -0
  38. package/dist/api/routes/workspaces.d.ts.map +1 -0
  39. package/dist/api/routes/workspaces.js +504 -0
  40. package/dist/api/routes/workspaces.js.map +1 -0
  41. package/dist/api/services/scanner.js +10 -19
  42. package/dist/api/services/scanner.js.map +1 -1
  43. package/dist/api/services/test-parser.js +3 -2
  44. package/dist/api/services/test-parser.js.map +1 -1
  45. package/dist/api/types.d.ts +31 -0
  46. package/dist/api/types.d.ts.map +1 -1
  47. package/dist/core/__tests__/database.test.js +7 -17
  48. package/dist/core/__tests__/detector.test.js +7 -17
  49. package/dist/core/__tests__/index.test.js +7 -17
  50. package/dist/core/__tests__/scanner.test.js +7 -17
  51. package/dist/core/__tests__/settings.test.js +7 -17
  52. package/dist/core/backup-utils.d.ts +17 -0
  53. package/dist/core/backup-utils.js +157 -0
  54. package/dist/core/database.d.ts +1 -0
  55. package/dist/core/database.js +9 -18
  56. package/dist/core/detector.js +11 -21
  57. package/dist/core/git-utils.d.ts +12 -0
  58. package/dist/core/git-utils.js +87 -0
  59. package/dist/core/index.d.ts +3 -0
  60. package/dist/core/index.js +8 -5
  61. package/dist/core/scanner.js +3 -2
  62. package/dist/core/settings.d.ts +85 -0
  63. package/dist/core/settings.js +306 -9
  64. package/dist/core/workspace-utils.d.ts +37 -0
  65. package/dist/core/workspace-utils.js +143 -0
  66. package/dist/core-bridge.js +7 -17
  67. package/dist/electron/core/__tests__/database.test.js +7 -17
  68. package/dist/electron/core/__tests__/detector.test.js +7 -17
  69. package/dist/electron/core/__tests__/index.test.js +7 -17
  70. package/dist/electron/core/__tests__/scanner.test.js +7 -17
  71. package/dist/electron/core/__tests__/settings.test.js +7 -17
  72. package/dist/electron/core/backup-utils.d.ts +17 -0
  73. package/dist/electron/core/backup-utils.js +157 -0
  74. package/dist/electron/core/database.d.ts +1 -0
  75. package/dist/electron/core/database.js +9 -18
  76. package/dist/electron/core/detector.js +11 -21
  77. package/dist/electron/core/git-utils.d.ts +12 -0
  78. package/dist/electron/core/git-utils.js +87 -0
  79. package/dist/electron/core/index.d.ts +3 -0
  80. package/dist/electron/core/index.js +8 -5
  81. package/dist/electron/core/scanner.js +3 -2
  82. package/dist/electron/core/settings.d.ts +85 -0
  83. package/dist/electron/core/settings.js +306 -9
  84. package/dist/electron/core/workspace-utils.d.ts +37 -0
  85. package/dist/electron/core/workspace-utils.js +143 -0
  86. package/dist/electron/core.js +7 -17
  87. package/dist/electron/main.js +663 -33
  88. package/dist/electron/port-extractor.js +9 -18
  89. package/dist/electron/port-scanner.js +11 -20
  90. package/dist/electron/port-utils.js +5 -4
  91. package/dist/electron/preload.d.ts +27 -2
  92. package/dist/electron/preload.js +18 -2
  93. package/dist/electron/renderer/assets/index-B-etDnj2.js +64 -0
  94. package/dist/electron/renderer/assets/index-Bx18Cyic.js +64 -0
  95. package/dist/electron/renderer/assets/index-C8f5yNYe.js +64 -0
  96. package/dist/electron/renderer/assets/index-CIZ3Wl6c.css +1 -0
  97. package/dist/electron/renderer/assets/index-CJbsU9y8.css +1 -0
  98. package/dist/electron/renderer/assets/index-CopVNRnR.js +64 -0
  99. package/dist/electron/renderer/assets/index-DUvcepWm.js +64 -0
  100. package/dist/electron/renderer/assets/index-DWe2TQFv.css +1 -0
  101. package/dist/electron/renderer/assets/index-DZzB20Xf.css +1 -0
  102. package/dist/electron/renderer/assets/index-DknLdADV.js +63 -0
  103. package/dist/electron/renderer/assets/index-DocuD8Lk.js +64 -0
  104. package/dist/electron/renderer/assets/index-DyU-xfd8.css +1 -0
  105. package/dist/electron/renderer/assets/index-GwC-JVUy.css +1 -0
  106. package/dist/electron/renderer/assets/index-fehviker.js +63 -0
  107. package/dist/electron/renderer/index.html +2 -2
  108. package/dist/electron/script-runner.js +20 -29
  109. package/dist/index.js +395 -21
  110. package/dist/port-extractor.js +9 -18
  111. package/dist/port-scanner.js +11 -20
  112. package/dist/port-utils.js +5 -4
  113. package/dist/script-runner.js +20 -29
  114. package/dist/test-parser.js +3 -2
  115. package/package.json +3 -2
@@ -0,0 +1,143 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.validateWorkspacePath = exports.generateWorkspaceFile = exports.parseWorkspaceFile = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ /**
30
+ * Parse a .code-workspace file
31
+ * @param filePath Path to the .code-workspace file
32
+ * @returns Parsed workspace structure
33
+ */
34
+ function parseWorkspaceFile(filePath) {
35
+ if (!fs.existsSync(filePath)) {
36
+ throw new Error(`Workspace file not found: ${filePath}`);
37
+ }
38
+ try {
39
+ const content = fs.readFileSync(filePath, 'utf-8');
40
+ const workspace = JSON.parse(content);
41
+ // Validate structure
42
+ if (!workspace.folders || !Array.isArray(workspace.folders)) {
43
+ throw new Error('Invalid workspace file: missing or invalid folders array');
44
+ }
45
+ // Normalize folder paths to absolute paths
46
+ const workspaceDir = path.dirname(filePath);
47
+ workspace.folders = workspace.folders.map(folder => {
48
+ if (typeof folder === 'string') {
49
+ // Legacy format: folders can be strings
50
+ const absolutePath = path.isAbsolute(folder)
51
+ ? folder
52
+ : path.resolve(workspaceDir, folder);
53
+ return { path: absolutePath };
54
+ }
55
+ else {
56
+ // Modern format: folders are objects with path property
57
+ const absolutePath = path.isAbsolute(folder.path)
58
+ ? folder.path
59
+ : path.resolve(workspaceDir, folder.path);
60
+ return {
61
+ ...folder,
62
+ path: absolutePath,
63
+ };
64
+ }
65
+ });
66
+ return workspace;
67
+ }
68
+ catch (error) {
69
+ if (error instanceof SyntaxError) {
70
+ throw new Error(`Invalid JSON in workspace file: ${error.message}`);
71
+ }
72
+ throw error;
73
+ }
74
+ }
75
+ exports.parseWorkspaceFile = parseWorkspaceFile;
76
+ /**
77
+ * Generate a .code-workspace file
78
+ * @param workspaceName Name of the workspace (used in comments)
79
+ * @param projects Array of project paths (absolute or relative)
80
+ * @param outputPath Path where the .code-workspace file should be created
81
+ * @param settings Optional workspace settings
82
+ * @param extensions Optional workspace extensions recommendations
83
+ */
84
+ function generateWorkspaceFile(workspaceName, projects, outputPath, settings, extensions) {
85
+ const workspaceDir = path.dirname(outputPath);
86
+ // Convert project paths to relative paths if they're within the workspace directory
87
+ const folders = projects.map(projectPath => {
88
+ const absolutePath = path.isAbsolute(projectPath)
89
+ ? projectPath
90
+ : path.resolve(process.cwd(), projectPath);
91
+ // Try to make path relative to workspace directory if possible
92
+ let relativePath;
93
+ try {
94
+ relativePath = path.relative(workspaceDir, absolutePath);
95
+ // If relative path goes outside workspace dir, use absolute
96
+ if (relativePath.startsWith('..')) {
97
+ relativePath = absolutePath;
98
+ }
99
+ }
100
+ catch {
101
+ relativePath = absolutePath;
102
+ }
103
+ return {
104
+ path: relativePath,
105
+ };
106
+ });
107
+ const workspace = {
108
+ folders,
109
+ ...(settings && { settings }),
110
+ ...(extensions && { extensions }),
111
+ };
112
+ // Add comment header
113
+ const content = JSON.stringify(workspace, null, 2);
114
+ const withHeader = `// ${workspaceName} Workspace\n${content}`;
115
+ // Ensure output directory exists
116
+ const outputDir = path.dirname(outputPath);
117
+ if (!fs.existsSync(outputDir)) {
118
+ fs.mkdirSync(outputDir, { recursive: true });
119
+ }
120
+ fs.writeFileSync(outputPath, withHeader, 'utf-8');
121
+ }
122
+ exports.generateWorkspaceFile = generateWorkspaceFile;
123
+ /**
124
+ * Validate that a path is a valid workspace file
125
+ * @param filePath Path to check
126
+ * @returns true if the path exists and is a valid .code-workspace file
127
+ */
128
+ function validateWorkspacePath(filePath) {
129
+ if (!fs.existsSync(filePath)) {
130
+ return false;
131
+ }
132
+ if (!filePath.endsWith('.code-workspace')) {
133
+ return false;
134
+ }
135
+ try {
136
+ parseWorkspaceFile(filePath);
137
+ return true;
138
+ }
139
+ catch {
140
+ return false;
141
+ }
142
+ }
143
+ exports.validateWorkspacePath = validateWorkspacePath;
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  exports.scanAllProjects = exports.scanProject = exports.removeProject = exports.addProject = exports.getAllProjects = exports.getDatabaseManager = void 0;
37
27
  const path = __importStar(require("path"));
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  const fs = __importStar(require("fs"));
37
27
  const os = __importStar(require("os"));
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  const fs = __importStar(require("fs"));
37
27
  const path = __importStar(require("path"));
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  const fs = __importStar(require("fs"));
37
27
  const child_process_1 = require("child_process");
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  const fs = __importStar(require("fs"));
37
27
  const child_process_1 = require("child_process");
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  const fs = __importStar(require("fs"));
37
27
  const child_process_1 = require("child_process");
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Create a backup of the PROJAX database
3
+ * @param outputPath Directory where the backup should be created
4
+ * @returns Path to the created backup file
5
+ */
6
+ export declare function createBackup(outputPath: string): Promise<string>;
7
+ /**
8
+ * Restore PROJAX database from a backup file
9
+ * @param backupPath Path to the .pbz backup file
10
+ */
11
+ export declare function restoreBackup(backupPath: string): Promise<void>;
12
+ /**
13
+ * Validate a backup file without restoring
14
+ * @param backupPath Path to the .pbz backup file
15
+ * @returns true if valid, throws error if invalid
16
+ */
17
+ export declare function validateBackup(backupPath: string): Promise<boolean>;
@@ -0,0 +1,157 @@
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.validateBackup = exports.restoreBackup = exports.createBackup = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const os = __importStar(require("os"));
30
+ /**
31
+ * Create a backup of the PROJAX database
32
+ * @param outputPath Directory where the backup should be created
33
+ * @returns Path to the created backup file
34
+ */
35
+ async function createBackup(outputPath) {
36
+ const dataDir = path.join(os.homedir(), '.projax');
37
+ const dbPath = path.join(dataDir, 'data.json');
38
+ if (!fs.existsSync(dbPath)) {
39
+ throw new Error('PROJAX database not found');
40
+ }
41
+ // Generate timestamped filename
42
+ const now = new Date();
43
+ const timestamp = now.toISOString().replace(/[:.]/g, '-').slice(0, 19); // YYYY-MM-DDTHHmmss
44
+ const filename = `projax-backup-${timestamp}.pbz`;
45
+ const backupPath = path.join(outputPath, filename);
46
+ // Ensure output directory exists
47
+ if (!fs.existsSync(outputPath)) {
48
+ fs.mkdirSync(outputPath, { recursive: true });
49
+ }
50
+ // Read database file
51
+ const dbContent = fs.readFileSync(dbPath, 'utf-8');
52
+ // Create metadata
53
+ const metadata = {
54
+ version: '1.0',
55
+ timestamp: Math.floor(Date.now() / 1000),
56
+ projax_version: '3.4.0', // This should ideally come from package.json
57
+ created_at: now.toISOString(),
58
+ };
59
+ // Create ZIP-like structure manually (simple approach)
60
+ // For a proper ZIP, we'd use a library like adm-zip or archiver
61
+ // For now, we'll create a simple JSON structure that can be restored
62
+ const backupData = {
63
+ metadata,
64
+ data: JSON.parse(dbContent),
65
+ };
66
+ // Write backup file
67
+ fs.writeFileSync(backupPath, JSON.stringify(backupData, null, 2), 'utf-8');
68
+ return backupPath;
69
+ }
70
+ exports.createBackup = createBackup;
71
+ /**
72
+ * Restore PROJAX database from a backup file
73
+ * @param backupPath Path to the .pbz backup file
74
+ */
75
+ async function restoreBackup(backupPath) {
76
+ if (!fs.existsSync(backupPath)) {
77
+ throw new Error(`Backup file not found: ${backupPath}`);
78
+ }
79
+ if (!backupPath.endsWith('.pbz')) {
80
+ throw new Error('Invalid backup file extension. Expected .pbz');
81
+ }
82
+ // Read and parse backup file
83
+ let backupContent;
84
+ try {
85
+ const content = fs.readFileSync(backupPath, 'utf-8');
86
+ backupContent = JSON.parse(content);
87
+ }
88
+ catch (error) {
89
+ if (error instanceof SyntaxError) {
90
+ throw new Error(`Invalid backup file format: ${error.message}`);
91
+ }
92
+ throw new Error(`Failed to read backup file: ${error instanceof Error ? error.message : 'Unknown error'}`);
93
+ }
94
+ // Validate backup structure
95
+ if (!backupContent.metadata || !backupContent.data) {
96
+ throw new Error('Invalid backup file structure: missing metadata or data');
97
+ }
98
+ // Validate metadata
99
+ const metadata = backupContent.metadata;
100
+ if (!metadata.version || !metadata.timestamp) {
101
+ throw new Error('Invalid backup metadata');
102
+ }
103
+ // Validate data structure (basic check)
104
+ if (typeof backupContent.data !== 'object' || !Array.isArray(backupContent.data.projects)) {
105
+ throw new Error('Invalid backup data structure');
106
+ }
107
+ // Create backup of current database before restoring
108
+ const dataDir = path.join(os.homedir(), '.projax');
109
+ const dbPath = path.join(dataDir, 'data.json');
110
+ if (fs.existsSync(dbPath)) {
111
+ const backupTimestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
112
+ const currentBackupPath = path.join(dataDir, `data.backup-${backupTimestamp}.json`);
113
+ fs.copyFileSync(dbPath, currentBackupPath);
114
+ }
115
+ // Ensure data directory exists
116
+ if (!fs.existsSync(dataDir)) {
117
+ fs.mkdirSync(dataDir, { recursive: true });
118
+ }
119
+ // Write restored data
120
+ fs.writeFileSync(dbPath, JSON.stringify(backupContent.data, null, 2), 'utf-8');
121
+ }
122
+ exports.restoreBackup = restoreBackup;
123
+ /**
124
+ * Validate a backup file without restoring
125
+ * @param backupPath Path to the .pbz backup file
126
+ * @returns true if valid, throws error if invalid
127
+ */
128
+ async function validateBackup(backupPath) {
129
+ if (!fs.existsSync(backupPath)) {
130
+ throw new Error(`Backup file not found: ${backupPath}`);
131
+ }
132
+ if (!backupPath.endsWith('.pbz')) {
133
+ throw new Error('Invalid backup file extension. Expected .pbz');
134
+ }
135
+ try {
136
+ const content = fs.readFileSync(backupPath, 'utf-8');
137
+ const backupContent = JSON.parse(content);
138
+ if (!backupContent.metadata || !backupContent.data) {
139
+ throw new Error('Invalid backup file structure');
140
+ }
141
+ const metadata = backupContent.metadata;
142
+ if (!metadata.version || !metadata.timestamp) {
143
+ throw new Error('Invalid backup metadata');
144
+ }
145
+ if (typeof backupContent.data !== 'object' || !Array.isArray(backupContent.data.projects)) {
146
+ throw new Error('Invalid backup data structure');
147
+ }
148
+ return true;
149
+ }
150
+ catch (error) {
151
+ if (error instanceof SyntaxError) {
152
+ throw new Error(`Invalid JSON in backup file: ${error.message}`);
153
+ }
154
+ throw error;
155
+ }
156
+ }
157
+ exports.validateBackup = validateBackup;
@@ -7,6 +7,7 @@ export interface Project {
7
7
  last_scanned: number | null;
8
8
  created_at: number;
9
9
  tags?: string[];
10
+ git_branch?: string | null;
10
11
  }
11
12
  export interface Test {
12
13
  id: number;
@@ -15,25 +15,15 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.getDatabaseManager = getDatabaseManager;
26
+ exports.getDatabaseManager = void 0;
37
27
  const path = __importStar(require("path"));
38
28
  const os = __importStar(require("os"));
39
29
  const fs = __importStar(require("fs"));
@@ -272,3 +262,4 @@ function getDatabaseManager() {
272
262
  }
273
263
  return dbManager;
274
264
  }
265
+ exports.getDatabaseManager = getDatabaseManager;
@@ -15,28 +15,15 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.FRAMEWORKS = void 0;
37
- exports.detectTestFramework = detectTestFramework;
38
- exports.isTestFile = isTestFile;
39
- exports.detectProjectFramework = detectProjectFramework;
26
+ exports.detectProjectFramework = exports.isTestFile = exports.detectTestFramework = exports.FRAMEWORKS = void 0;
40
27
  const fs = __importStar(require("fs"));
41
28
  const path = __importStar(require("path"));
42
29
  exports.FRAMEWORKS = [
@@ -111,6 +98,7 @@ function detectTestFramework(projectPath) {
111
98
  }
112
99
  return null;
113
100
  }
101
+ exports.detectTestFramework = detectTestFramework;
114
102
  function isTestFile(filePath, detectedFramework = null) {
115
103
  const fileName = path.basename(filePath);
116
104
  const dirName = path.dirname(filePath);
@@ -148,6 +136,7 @@ function isTestFile(filePath, detectedFramework = null) {
148
136
  }
149
137
  return false;
150
138
  }
139
+ exports.isTestFile = isTestFile;
151
140
  /**
152
141
  * Detect the main framework/library used in a project
153
142
  * Returns null if no framework is detected
@@ -282,3 +271,4 @@ function detectProjectFramework(projectPath) {
282
271
  return null;
283
272
  }
284
273
  }
274
+ exports.detectProjectFramework = detectProjectFramework;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Get the current git branch for a project
3
+ * @param projectPath The path to the project directory
4
+ * @returns The current branch name, or null if not a git repo or on error
5
+ */
6
+ export declare function getCurrentBranch(projectPath: string): string | null;
7
+ /**
8
+ * Get git branches for multiple projects
9
+ * @param projectPaths Array of project paths
10
+ * @returns Map of project path to branch name (or null)
11
+ */
12
+ export declare function getBranchesForProjects(projectPaths: string[]): Map<string, string | null>;