@dollhousemcp/mcp-server 1.5.2 → 1.6.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/CHANGELOG.md +56 -0
- package/README.md +494 -111
- package/data/agents/code-reviewer.md +8 -1
- package/data/agents/research-assistant.md +8 -1
- package/data/agents/task-manager.md +8 -1
- package/data/ensembles/business-advisor.md +8 -1
- package/data/ensembles/creative-studio.md +8 -1
- package/data/ensembles/development-team.md +8 -1
- package/data/ensembles/security-analysis-team.md +8 -1
- package/data/memories/conversation-history.md +8 -1
- package/data/memories/learning-progress.md +8 -1
- package/data/memories/project-context.md +8 -1
- package/data/personas/business-consultant.md +8 -1
- package/data/personas/creative-writer.md +8 -1
- package/data/personas/debug-detective.md +8 -1
- package/data/personas/eli5-explainer.md +8 -1
- package/data/personas/security-analyst.md +8 -1
- package/data/personas/technical-analyst.md +8 -1
- package/data/skills/code-review.md +8 -1
- package/data/skills/creative-writing.md +8 -1
- package/data/skills/data-analysis.md +8 -1
- package/data/skills/penetration-testing.md +8 -1
- package/data/skills/research.md +8 -1
- package/data/skills/threat-modeling.md +8 -1
- package/data/skills/translation.md +8 -1
- package/data/templates/code-documentation.md +8 -1
- package/data/templates/email-professional.md +8 -1
- package/data/templates/meeting-notes.md +8 -1
- package/data/templates/penetration-test-report.md +8 -1
- package/data/templates/project-brief.md +8 -1
- package/data/templates/report-executive.md +8 -1
- package/data/templates/security-vulnerability-report.md +8 -1
- package/data/templates/threat-assessment-report.md +8 -1
- package/dist/auth/GitHubAuthManager.d.ts +6 -1
- package/dist/auth/GitHubAuthManager.d.ts.map +1 -1
- package/dist/auth/GitHubAuthManager.js +45 -18
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts +98 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.d.ts.map +1 -0
- package/dist/benchmarks/IndexPerformanceBenchmark.js +531 -0
- package/dist/cache/CollectionCache.d.ts.map +1 -1
- package/dist/cache/CollectionCache.js +13 -3
- package/dist/cache/CollectionIndexCache.d.ts +77 -0
- package/dist/cache/CollectionIndexCache.d.ts.map +1 -0
- package/dist/cache/CollectionIndexCache.js +349 -0
- package/dist/cache/LRUCache.d.ts +93 -0
- package/dist/cache/LRUCache.d.ts.map +1 -0
- package/dist/cache/LRUCache.js +299 -0
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +2 -1
- package/dist/collection/CollectionBrowser.d.ts +21 -1
- package/dist/collection/CollectionBrowser.d.ts.map +1 -1
- package/dist/collection/CollectionBrowser.js +130 -10
- package/dist/collection/CollectionIndexManager.d.ts +151 -0
- package/dist/collection/CollectionIndexManager.d.ts.map +1 -0
- package/dist/collection/CollectionIndexManager.js +499 -0
- package/dist/collection/CollectionSearch.d.ts +55 -0
- package/dist/collection/CollectionSearch.d.ts.map +1 -1
- package/dist/collection/CollectionSearch.js +338 -13
- package/dist/collection/CollectionSeeder.d.ts.map +1 -1
- package/dist/collection/CollectionSeeder.js +38 -1
- package/dist/collection/ElementInstaller.d.ts +31 -0
- package/dist/collection/ElementInstaller.d.ts.map +1 -1
- package/dist/collection/ElementInstaller.js +77 -15
- package/dist/collection/PersonaSubmitter.d.ts +1 -1
- package/dist/collection/PersonaSubmitter.d.ts.map +1 -1
- package/dist/collection/PersonaSubmitter.js +2 -2
- package/dist/collection/index.d.ts +1 -0
- package/dist/collection/index.d.ts.map +1 -1
- package/dist/collection/index.js +2 -1
- package/dist/config/ConfigManager.d.ts +78 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +216 -0
- package/dist/config/element-types.d.ts +135 -0
- package/dist/config/element-types.d.ts.map +1 -0
- package/dist/config/element-types.js +108 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -1
- package/dist/config/portfolio-constants.d.ts +83 -0
- package/dist/config/portfolio-constants.d.ts.map +1 -0
- package/dist/config/portfolio-constants.js +99 -0
- package/dist/elements/BaseElement.d.ts +14 -2
- package/dist/elements/BaseElement.d.ts.map +1 -1
- package/dist/elements/BaseElement.js +88 -6
- package/dist/elements/agents/Agent.d.ts +10 -1
- package/dist/elements/agents/Agent.d.ts.map +1 -1
- package/dist/elements/agents/Agent.js +66 -19
- package/dist/elements/agents/AgentManager.d.ts +2 -0
- package/dist/elements/agents/AgentManager.d.ts.map +1 -1
- package/dist/elements/agents/AgentManager.js +12 -10
- package/dist/elements/skills/Skill.d.ts +10 -1
- package/dist/elements/skills/Skill.d.ts.map +1 -1
- package/dist/elements/skills/Skill.js +40 -3
- package/dist/elements/skills/SkillManager.d.ts +1 -0
- package/dist/elements/skills/SkillManager.d.ts.map +1 -1
- package/dist/elements/skills/SkillManager.js +10 -4
- package/dist/elements/templates/Template.d.ts +10 -1
- package/dist/elements/templates/Template.d.ts.map +1 -1
- package/dist/elements/templates/Template.js +35 -18
- package/dist/elements/templates/TemplateManager.d.ts +1 -1
- package/dist/elements/templates/TemplateManager.d.ts.map +1 -1
- package/dist/elements/templates/TemplateManager.js +6 -5
- package/dist/generated/version.d.ts +2 -2
- package/dist/generated/version.js +3 -3
- package/dist/index.barrel.d.ts +1 -2
- package/dist/index.barrel.d.ts.map +1 -1
- package/dist/index.barrel.js +2 -4
- package/dist/index.d.ts +143 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1883 -310
- package/dist/persona/PersonaElement.d.ts +10 -0
- package/dist/persona/PersonaElement.d.ts.map +1 -1
- package/dist/persona/PersonaElement.js +55 -32
- package/dist/persona/PersonaElementManager.d.ts.map +1 -1
- package/dist/persona/PersonaElementManager.js +13 -11
- package/dist/persona/PersonaLoader.d.ts.map +1 -1
- package/dist/persona/PersonaLoader.js +8 -2
- package/dist/persona/export-import/PersonaImporter.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaImporter.js +24 -5
- package/dist/persona/export-import/PersonaSharer.d.ts +21 -0
- package/dist/persona/export-import/PersonaSharer.d.ts.map +1 -1
- package/dist/persona/export-import/PersonaSharer.js +198 -22
- package/dist/portfolio/DefaultElementProvider.d.ts +90 -0
- package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -1
- package/dist/portfolio/DefaultElementProvider.js +499 -7
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts +129 -0
- package/dist/portfolio/GitHubPortfolioIndexer.d.ts.map +1 -0
- package/dist/portfolio/GitHubPortfolioIndexer.js +475 -0
- package/dist/portfolio/MigrationManager.d.ts.map +1 -1
- package/dist/portfolio/MigrationManager.js +136 -3
- package/dist/portfolio/PortfolioIndexManager.d.ts +130 -0
- package/dist/portfolio/PortfolioIndexManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioIndexManager.js +478 -0
- package/dist/portfolio/PortfolioManager.d.ts +5 -0
- package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
- package/dist/portfolio/PortfolioManager.js +61 -20
- package/dist/portfolio/PortfolioRepoManager.d.ts +75 -0
- package/dist/portfolio/PortfolioRepoManager.d.ts.map +1 -0
- package/dist/portfolio/PortfolioRepoManager.js +337 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts +388 -0
- package/dist/portfolio/UnifiedIndexManager.d.ts.map +1 -0
- package/dist/portfolio/UnifiedIndexManager.js +1434 -0
- package/dist/portfolio/index.d.ts +15 -0
- package/dist/portfolio/index.d.ts.map +1 -0
- package/dist/portfolio/index.js +15 -0
- package/dist/portfolio/types.d.ts +7 -0
- package/dist/portfolio/types.d.ts.map +1 -1
- package/dist/portfolio/types.js +6 -1
- package/dist/security/InputValidator.d.ts.map +1 -1
- package/dist/security/InputValidator.js +50 -48
- package/dist/security/audit/SecurityAuditor.d.ts.map +1 -1
- package/dist/security/audit/SecurityAuditor.js +17 -9
- package/dist/security/audit/config/suppressions.d.ts.map +1 -1
- package/dist/security/audit/config/suppressions.js +19 -3
- package/dist/security/contentValidator.d.ts +2 -0
- package/dist/security/contentValidator.d.ts.map +1 -1
- package/dist/security/contentValidator.js +115 -4
- package/dist/security/secureYamlParser.d.ts +1 -0
- package/dist/security/secureYamlParser.d.ts.map +1 -1
- package/dist/security/secureYamlParser.js +29 -7
- package/dist/security/securityMonitor.d.ts +1 -1
- package/dist/security/securityMonitor.d.ts.map +1 -1
- package/dist/security/securityMonitor.js +1 -1
- package/dist/security/tokenManager.d.ts +1 -1
- package/dist/security/tokenManager.d.ts.map +1 -1
- package/dist/security/tokenManager.js +30 -10
- package/dist/server/ServerSetup.d.ts +22 -2
- package/dist/server/ServerSetup.d.ts.map +1 -1
- package/dist/server/ServerSetup.js +77 -12
- package/dist/server/tools/AuthTools.d.ts.map +1 -1
- package/dist/server/tools/AuthTools.js +33 -1
- package/dist/server/tools/BuildInfoTools.d.ts +25 -0
- package/dist/server/tools/BuildInfoTools.d.ts.map +1 -0
- package/dist/server/tools/BuildInfoTools.js +36 -0
- package/dist/server/tools/CollectionTools.d.ts.map +1 -1
- package/dist/server/tools/CollectionTools.js +55 -46
- package/dist/server/tools/ConfigTools.d.ts.map +1 -1
- package/dist/server/tools/ConfigTools.js +29 -1
- package/dist/server/tools/PersonaTools.d.ts +4 -2
- package/dist/server/tools/PersonaTools.d.ts.map +1 -1
- package/dist/server/tools/PersonaTools.js +5 -152
- package/dist/server/tools/PortfolioTools.d.ts +12 -0
- package/dist/server/tools/PortfolioTools.d.ts.map +1 -0
- package/dist/server/tools/PortfolioTools.js +221 -0
- package/dist/server/tools/index.d.ts +3 -1
- package/dist/server/tools/index.d.ts.map +1 -1
- package/dist/server/tools/index.js +4 -2
- package/dist/server/types.d.ts +40 -5
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +1 -1
- package/dist/services/BuildInfoService.d.ts +84 -0
- package/dist/services/BuildInfoService.d.ts.map +1 -0
- package/dist/services/BuildInfoService.js +271 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts +54 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.d.ts.map +1 -0
- package/dist/tools/portfolio/PortfolioElementAdapter.js +229 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts +164 -0
- package/dist/tools/portfolio/submitToPortfolioTool.d.ts.map +1 -0
- package/dist/tools/portfolio/submitToPortfolioTool.js +1523 -0
- package/dist/tools/portfolio/types.d.ts +41 -0
- package/dist/tools/portfolio/types.d.ts.map +1 -0
- package/dist/tools/portfolio/types.js +15 -0
- package/dist/types/collection.d.ts +51 -0
- package/dist/types/collection.d.ts.map +1 -1
- package/dist/types/collection.js +1 -1
- package/dist/utils/EarlyTerminationSearch.d.ts +41 -0
- package/dist/utils/EarlyTerminationSearch.d.ts.map +1 -0
- package/dist/utils/EarlyTerminationSearch.js +164 -0
- package/dist/utils/ErrorHandler.d.ts +86 -0
- package/dist/utils/ErrorHandler.d.ts.map +1 -0
- package/dist/utils/ErrorHandler.js +201 -0
- package/dist/utils/FileDiscoveryUtil.d.ts +53 -0
- package/dist/utils/FileDiscoveryUtil.d.ts.map +1 -0
- package/dist/utils/FileDiscoveryUtil.js +169 -0
- package/dist/utils/GitHubRateLimiter.d.ts +88 -0
- package/dist/utils/GitHubRateLimiter.d.ts.map +1 -0
- package/dist/utils/GitHubRateLimiter.js +315 -0
- package/dist/utils/PerformanceMonitor.d.ts +134 -0
- package/dist/utils/PerformanceMonitor.d.ts.map +1 -0
- package/dist/utils/PerformanceMonitor.js +347 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +172 -0
- package/dist/utils/SecureDownloader.d.ts +241 -0
- package/dist/utils/SecureDownloader.d.ts.map +1 -0
- package/dist/utils/SecureDownloader.js +759 -0
- package/dist/utils/ToolCache.d.ts +82 -0
- package/dist/utils/ToolCache.d.ts.map +1 -0
- package/dist/utils/ToolCache.js +196 -0
- package/dist/utils/errorCodes.d.ts +136 -0
- package/dist/utils/errorCodes.d.ts.map +1 -0
- package/dist/utils/errorCodes.js +87 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -1
- package/dist/utils/installation.d.ts +1 -1
- package/dist/utils/installation.d.ts.map +1 -1
- package/dist/utils/installation.js +9 -8
- package/dist/utils/searchUtils.d.ts +31 -0
- package/dist/utils/searchUtils.d.ts.map +1 -1
- package/dist/utils/searchUtils.js +62 -1
- package/package.json +17 -7
- package/dist/config/updateConfig.d.ts +0 -84
- package/dist/config/updateConfig.d.ts.map +0 -1
- package/dist/config/updateConfig.js +0 -148
- package/dist/server/tools/UpdateTools.d.ts +0 -10
- package/dist/server/tools/UpdateTools.d.ts.map +0 -1
- package/dist/server/tools/UpdateTools.js +0 -85
- package/dist/update/BackupManager.d.ts +0 -63
- package/dist/update/BackupManager.d.ts.map +0 -1
- package/dist/update/BackupManager.js +0 -370
- package/dist/update/DependencyChecker.d.ts +0 -41
- package/dist/update/DependencyChecker.d.ts.map +0 -1
- package/dist/update/DependencyChecker.js +0 -132
- package/dist/update/RateLimiter.d.ts.map +0 -1
- package/dist/update/RateLimiter.js +0 -172
- package/dist/update/SignatureVerifier.d.ts +0 -71
- package/dist/update/SignatureVerifier.d.ts.map +0 -1
- package/dist/update/SignatureVerifier.js +0 -214
- package/dist/update/UpdateChecker.d.ts +0 -132
- package/dist/update/UpdateChecker.d.ts.map +0 -1
- package/dist/update/UpdateChecker.js +0 -506
- package/dist/update/UpdateManager.d.ts +0 -60
- package/dist/update/UpdateManager.d.ts.map +0 -1
- package/dist/update/UpdateManager.js +0 -730
- package/dist/update/VersionManager.d.ts +0 -31
- package/dist/update/VersionManager.d.ts.map +0 -1
- package/dist/update/VersionManager.js +0 -181
- package/dist/update/index.d.ts +0 -9
- package/dist/update/index.d.ts.map +0 -1
- package/dist/update/index.js +0 -9
- /package/dist/{update → utils}/RateLimiter.d.ts +0 -0
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Update/maintenance-related tool definitions and handlers
|
|
3
|
-
*/
|
|
4
|
-
export function getUpdateTools(server) {
|
|
5
|
-
return [
|
|
6
|
-
{
|
|
7
|
-
tool: {
|
|
8
|
-
name: "check_for_updates",
|
|
9
|
-
description: "Check if a newer version of DollhouseMCP is available",
|
|
10
|
-
inputSchema: {
|
|
11
|
-
type: "object",
|
|
12
|
-
properties: {},
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
handler: () => server.checkForUpdates()
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
tool: {
|
|
19
|
-
name: "update_server",
|
|
20
|
-
description: "Update DollhouseMCP to the latest version from GitHub",
|
|
21
|
-
inputSchema: {
|
|
22
|
-
type: "object",
|
|
23
|
-
properties: {
|
|
24
|
-
confirm: {
|
|
25
|
-
type: "boolean",
|
|
26
|
-
description: "Confirm the update (true to proceed, false for preview)",
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
required: ["confirm"],
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
handler: (args) => server.updateServer(args.confirm)
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
tool: {
|
|
36
|
-
name: "rollback_update",
|
|
37
|
-
description: "Rollback to the previous version from backup",
|
|
38
|
-
inputSchema: {
|
|
39
|
-
type: "object",
|
|
40
|
-
properties: {
|
|
41
|
-
confirm: {
|
|
42
|
-
type: "boolean",
|
|
43
|
-
description: "Confirm the rollback (true to proceed, false for info)",
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
required: ["confirm"],
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
handler: (args) => server.rollbackUpdate(args.confirm)
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
tool: {
|
|
53
|
-
name: "get_server_status",
|
|
54
|
-
description: "Get current server status, version, and system information",
|
|
55
|
-
inputSchema: {
|
|
56
|
-
type: "object",
|
|
57
|
-
properties: {},
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
handler: () => server.getServerStatus()
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
tool: {
|
|
64
|
-
name: "convert_to_git_installation",
|
|
65
|
-
description: "Convert from npm installation to git installation for more control over updates",
|
|
66
|
-
inputSchema: {
|
|
67
|
-
type: "object",
|
|
68
|
-
properties: {
|
|
69
|
-
targetDir: {
|
|
70
|
-
type: "string",
|
|
71
|
-
description: "Target directory for git installation (default: ~/.dollhouse/mcp-server-git)",
|
|
72
|
-
},
|
|
73
|
-
confirm: {
|
|
74
|
-
type: "boolean",
|
|
75
|
-
description: "Confirm the conversion (true to proceed, false for preview)",
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
required: ["confirm"],
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
handler: (args) => server.convertToGitInstallation(args.targetDir, args.confirm)
|
|
82
|
-
}
|
|
83
|
-
];
|
|
84
|
-
}
|
|
85
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVXBkYXRlVG9vbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmVyL3Rvb2xzL1VwZGF0ZVRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBS0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxNQUFvQjtJQUNqRCxPQUFPO1FBQ0w7WUFDRSxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsV0FBVyxFQUFFLHVEQUF1RDtnQkFDcEUsV0FBVyxFQUFFO29CQUNYLElBQUksRUFBRSxRQUFRO29CQUNkLFVBQVUsRUFBRSxFQUFFO2lCQUNmO2FBQ0Y7WUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRTtTQUN4QztRQUNEO1lBQ0UsSUFBSSxFQUFFO2dCQUNKLElBQUksRUFBRSxlQUFlO2dCQUNyQixXQUFXLEVBQUUsdURBQXVEO2dCQUNwRSxXQUFXLEVBQUU7b0JBQ1gsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsVUFBVSxFQUFFO3dCQUNWLE9BQU8sRUFBRTs0QkFDUCxJQUFJLEVBQUUsU0FBUzs0QkFDZixXQUFXLEVBQUUseURBQXlEO3lCQUN2RTtxQkFDRjtvQkFDRCxRQUFRLEVBQUUsQ0FBQyxTQUFTLENBQUM7aUJBQ3RCO2FBQ0Y7WUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztTQUMxRDtRQUNEO1lBQ0UsSUFBSSxFQUFFO2dCQUNKLElBQUksRUFBRSxpQkFBaUI7Z0JBQ3ZCLFdBQVcsRUFBRSw4Q0FBOEM7Z0JBQzNELFdBQVcsRUFBRTtvQkFDWCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxVQUFVLEVBQUU7d0JBQ1YsT0FBTyxFQUFFOzRCQUNQLElBQUksRUFBRSxTQUFTOzRCQUNmLFdBQVcsRUFBRSx3REFBd0Q7eUJBQ3RFO3FCQUNGO29CQUNELFFBQVEsRUFBRSxDQUFDLFNBQVMsQ0FBQztpQkFDdEI7YUFDRjtZQUNELE9BQU8sRUFBRSxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO1NBQzVEO1FBQ0Q7WUFDRSxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsV0FBVyxFQUFFLDREQUE0RDtnQkFDekUsV0FBVyxFQUFFO29CQUNYLElBQUksRUFBRSxRQUFRO29CQUNkLFVBQVUsRUFBRSxFQUFFO2lCQUNmO2FBQ0Y7WUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRTtTQUN4QztRQUNEO1lBQ0UsSUFBSSxFQUFFO2dCQUNKLElBQUksRUFBRSw2QkFBNkI7Z0JBQ25DLFdBQVcsRUFBRSxpRkFBaUY7Z0JBQzlGLFdBQVcsRUFBRTtvQkFDWCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxVQUFVLEVBQUU7d0JBQ1YsU0FBUyxFQUFFOzRCQUNULElBQUksRUFBRSxRQUFROzRCQUNkLFdBQVcsRUFBRSw4RUFBOEU7eUJBQzVGO3dCQUNELE9BQU8sRUFBRTs0QkFDUCxJQUFJLEVBQUUsU0FBUzs0QkFDZixXQUFXLEVBQUUsNkRBQTZEO3lCQUMzRTtxQkFDRjtvQkFDRCxRQUFRLEVBQUUsQ0FBQyxTQUFTLENBQUM7aUJBQ3RCO2FBQ0Y7WUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUM7U0FDdEY7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXBkYXRlL21haW50ZW5hbmNlLXJlbGF0ZWQgdG9vbCBkZWZpbml0aW9ucyBhbmQgaGFuZGxlcnNcbiAqL1xuXG5pbXBvcnQgeyBUb29sRGVmaW5pdGlvbiB9IGZyb20gJy4vVG9vbFJlZ2lzdHJ5LmpzJztcbmltcG9ydCB7IElUb29sSGFuZGxlciB9IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVwZGF0ZVRvb2xzKHNlcnZlcjogSVRvb2xIYW5kbGVyKTogQXJyYXk8eyB0b29sOiBUb29sRGVmaW5pdGlvbjsgaGFuZGxlcjogYW55IH0+IHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0b29sOiB7XG4gICAgICAgIG5hbWU6IFwiY2hlY2tfZm9yX3VwZGF0ZXNcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiQ2hlY2sgaWYgYSBuZXdlciB2ZXJzaW9uIG9mIERvbGxob3VzZU1DUCBpcyBhdmFpbGFibGVcIixcbiAgICAgICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHt9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGhhbmRsZXI6ICgpID0+IHNlcnZlci5jaGVja0ZvclVwZGF0ZXMoKVxuICAgIH0sXG4gICAge1xuICAgICAgdG9vbDoge1xuICAgICAgICBuYW1lOiBcInVwZGF0ZV9zZXJ2ZXJcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVXBkYXRlIERvbGxob3VzZU1DUCB0byB0aGUgbGF0ZXN0IHZlcnNpb24gZnJvbSBHaXRIdWJcIixcbiAgICAgICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIGNvbmZpcm06IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbmZpcm0gdGhlIHVwZGF0ZSAodHJ1ZSB0byBwcm9jZWVkLCBmYWxzZSBmb3IgcHJldmlldylcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXF1aXJlZDogW1wiY29uZmlybVwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBoYW5kbGVyOiAoYXJnczogYW55KSA9PiBzZXJ2ZXIudXBkYXRlU2VydmVyKGFyZ3MuY29uZmlybSlcbiAgICB9LFxuICAgIHtcbiAgICAgIHRvb2w6IHtcbiAgICAgICAgbmFtZTogXCJyb2xsYmFja191cGRhdGVcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiUm9sbGJhY2sgdG8gdGhlIHByZXZpb3VzIHZlcnNpb24gZnJvbSBiYWNrdXBcIixcbiAgICAgICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIGNvbmZpcm06IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbmZpcm0gdGhlIHJvbGxiYWNrICh0cnVlIHRvIHByb2NlZWQsIGZhbHNlIGZvciBpbmZvKVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHJlcXVpcmVkOiBbXCJjb25maXJtXCJdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGhhbmRsZXI6IChhcmdzOiBhbnkpID0+IHNlcnZlci5yb2xsYmFja1VwZGF0ZShhcmdzLmNvbmZpcm0pXG4gICAgfSxcbiAgICB7XG4gICAgICB0b29sOiB7XG4gICAgICAgIG5hbWU6IFwiZ2V0X3NlcnZlcl9zdGF0dXNcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiR2V0IGN1cnJlbnQgc2VydmVyIHN0YXR1cywgdmVyc2lvbiwgYW5kIHN5c3RlbSBpbmZvcm1hdGlvblwiLFxuICAgICAgICBpbnB1dFNjaGVtYToge1xuICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgcHJvcGVydGllczoge30sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgaGFuZGxlcjogKCkgPT4gc2VydmVyLmdldFNlcnZlclN0YXR1cygpXG4gICAgfSxcbiAgICB7XG4gICAgICB0b29sOiB7XG4gICAgICAgIG5hbWU6IFwiY29udmVydF90b19naXRfaW5zdGFsbGF0aW9uXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbnZlcnQgZnJvbSBucG0gaW5zdGFsbGF0aW9uIHRvIGdpdCBpbnN0YWxsYXRpb24gZm9yIG1vcmUgY29udHJvbCBvdmVyIHVwZGF0ZXNcIixcbiAgICAgICAgaW5wdXRTY2hlbWE6IHtcbiAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIHRhcmdldERpcjoge1xuICAgICAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUYXJnZXQgZGlyZWN0b3J5IGZvciBnaXQgaW5zdGFsbGF0aW9uIChkZWZhdWx0OiB+Ly5kb2xsaG91c2UvbWNwLXNlcnZlci1naXQpXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29uZmlybToge1xuICAgICAgICAgICAgICB0eXBlOiBcImJvb2xlYW5cIixcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQ29uZmlybSB0aGUgY29udmVyc2lvbiAodHJ1ZSB0byBwcm9jZWVkLCBmYWxzZSBmb3IgcHJldmlldylcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXF1aXJlZDogW1wiY29uZmlybVwiXSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBoYW5kbGVyOiAoYXJnczogYW55KSA9PiBzZXJ2ZXIuY29udmVydFRvR2l0SW5zdGFsbGF0aW9uKGFyZ3MudGFyZ2V0RGlyLCBhcmdzLmNvbmZpcm0pXG4gICAgfVxuICBdO1xufSJdfQ==
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Manage backups during updates
|
|
3
|
-
*/
|
|
4
|
-
export interface BackupInfo {
|
|
5
|
-
path: string;
|
|
6
|
-
timestamp: string;
|
|
7
|
-
version?: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class BackupManager {
|
|
10
|
-
private rootDir;
|
|
11
|
-
private backupsDir;
|
|
12
|
-
constructor(rootDir?: string);
|
|
13
|
-
/**
|
|
14
|
-
* Check if the directory contains production files
|
|
15
|
-
*/
|
|
16
|
-
private hasProductionFiles;
|
|
17
|
-
/**
|
|
18
|
-
* Check if this appears to be a safe test directory
|
|
19
|
-
*/
|
|
20
|
-
private isSafeTestDirectory;
|
|
21
|
-
/**
|
|
22
|
-
* Check if running in a Docker container
|
|
23
|
-
*/
|
|
24
|
-
private isDockerEnvironment;
|
|
25
|
-
/**
|
|
26
|
-
* Create a backup of the current installation
|
|
27
|
-
*/
|
|
28
|
-
createBackup(version?: string): Promise<BackupInfo>;
|
|
29
|
-
/**
|
|
30
|
-
* Create a backup specifically for npm installations
|
|
31
|
-
*/
|
|
32
|
-
createNpmBackup(npmGlobalPath: string, version?: string): Promise<string>;
|
|
33
|
-
/**
|
|
34
|
-
* Copy directory recursively with progress reporting
|
|
35
|
-
* @deprecated Use FileOperations.copyDirectory instead
|
|
36
|
-
*/
|
|
37
|
-
private copyDirectory;
|
|
38
|
-
/**
|
|
39
|
-
* Update npm backup manifest
|
|
40
|
-
*/
|
|
41
|
-
private updateNpmBackupManifest;
|
|
42
|
-
/**
|
|
43
|
-
* Clean up old npm backups
|
|
44
|
-
*/
|
|
45
|
-
private cleanupOldNpmBackups;
|
|
46
|
-
/**
|
|
47
|
-
* List available backups
|
|
48
|
-
*/
|
|
49
|
-
listBackups(): Promise<BackupInfo[]>;
|
|
50
|
-
/**
|
|
51
|
-
* Get the most recent backup
|
|
52
|
-
*/
|
|
53
|
-
getLatestBackup(): Promise<BackupInfo | null>;
|
|
54
|
-
/**
|
|
55
|
-
* Restore from a backup
|
|
56
|
-
*/
|
|
57
|
-
restoreBackup(backupPath: string): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Clean up old backups (keep the 5 most recent)
|
|
60
|
-
*/
|
|
61
|
-
cleanupOldBackups(keepCount?: number): Promise<number>;
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=BackupManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BackupManager.d.ts","sourceRoot":"","sources":["../../src/update/BackupManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,CAAC,EAAE,MAAM;IAyB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAwB3B;;OAEG;IACG,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuFzD;;OAEG;IACG,eAAe,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmD/E;;;OAGG;YACW,aAAa;IAW3B;;OAEG;YACW,uBAAuB;IA8BrC;;OAEG;YACW,oBAAoB;IAqBlC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAmC1C;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAKnD;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCtD;;OAEG;IACG,iBAAiB,CAAC,SAAS,GAAE,MAAU,GAAG,OAAO,CAAC,MAAM,CAAC;CAmBhE"}
|
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Manage backups during updates
|
|
3
|
-
*/
|
|
4
|
-
import * as fs from 'fs/promises';
|
|
5
|
-
import * as fsSync from 'fs';
|
|
6
|
-
import * as path from 'path';
|
|
7
|
-
import { safeExec } from '../utils/git.js';
|
|
8
|
-
import { logger } from '../utils/logger.js';
|
|
9
|
-
import { FileOperations } from '../utils/fileOperations.js';
|
|
10
|
-
export class BackupManager {
|
|
11
|
-
rootDir;
|
|
12
|
-
backupsDir;
|
|
13
|
-
constructor(rootDir) {
|
|
14
|
-
// Validate rootDir parameter if provided
|
|
15
|
-
if (rootDir) {
|
|
16
|
-
// Prevent path traversal attacks first
|
|
17
|
-
if (rootDir.includes('../') || rootDir.includes('..\\')) {
|
|
18
|
-
throw new Error('rootDir cannot contain path traversal sequences');
|
|
19
|
-
}
|
|
20
|
-
// Then check if it's absolute
|
|
21
|
-
if (!path.isAbsolute(rootDir)) {
|
|
22
|
-
throw new Error('rootDir must be an absolute path');
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
// Allow override for testing, default to process.cwd()
|
|
26
|
-
this.rootDir = rootDir || process.cwd();
|
|
27
|
-
// Safety check: Don't allow operations on directories containing critical files
|
|
28
|
-
// This prevents accidental deletion of the actual project directory
|
|
29
|
-
if (this.hasProductionFiles() && !this.isSafeTestDirectory()) {
|
|
30
|
-
throw new Error('BackupManager cannot operate on production directory. Pass a safe test directory to the constructor.');
|
|
31
|
-
}
|
|
32
|
-
this.backupsDir = path.join(this.rootDir, "..", "dollhousemcp-backups");
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if the directory contains production files
|
|
36
|
-
*/
|
|
37
|
-
hasProductionFiles() {
|
|
38
|
-
try {
|
|
39
|
-
const productionIndicators = [
|
|
40
|
-
'package.json',
|
|
41
|
-
'tsconfig.json',
|
|
42
|
-
'.git',
|
|
43
|
-
'src',
|
|
44
|
-
'LICENSE'
|
|
45
|
-
];
|
|
46
|
-
const files = fsSync.readdirSync(this.rootDir);
|
|
47
|
-
const hasProductionFile = productionIndicators.some(indicator => files.includes(indicator));
|
|
48
|
-
// Additional check: if package.json exists, check if it's a real project
|
|
49
|
-
if (hasProductionFile && files.includes('package.json')) {
|
|
50
|
-
const packageJsonPath = path.join(this.rootDir, 'package.json');
|
|
51
|
-
const packageJson = JSON.parse(fsSync.readFileSync(packageJsonPath, 'utf-8'));
|
|
52
|
-
// If it has a name and dependencies, it's likely a real project
|
|
53
|
-
return !!(packageJson.name && packageJson.dependencies);
|
|
54
|
-
}
|
|
55
|
-
return hasProductionFile;
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// If we can't read the directory, assume it's safe
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Check if this appears to be a safe test directory
|
|
64
|
-
*/
|
|
65
|
-
isSafeTestDirectory() {
|
|
66
|
-
const safePaths = ['test', 'tmp', 'temp', '.test', '__test__'];
|
|
67
|
-
const dirPath = this.rootDir.toLowerCase();
|
|
68
|
-
// Check if running in Docker container
|
|
69
|
-
if (this.isDockerEnvironment()) {
|
|
70
|
-
return true; // Docker containers are immutable, updates don't apply
|
|
71
|
-
}
|
|
72
|
-
return safePaths.some(safe => dirPath.includes(safe));
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Check if running in a Docker container
|
|
76
|
-
*/
|
|
77
|
-
isDockerEnvironment() {
|
|
78
|
-
// Check common Docker indicators
|
|
79
|
-
if (process.env.DOLLHOUSE_DISABLE_UPDATES === 'true') {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
// Check if running from /app directory (common Docker practice)
|
|
83
|
-
if (this.rootDir === '/app') {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
// Check for Docker-specific files
|
|
87
|
-
try {
|
|
88
|
-
const hasDockerEnv = fsSync.existsSync('/.dockerenv');
|
|
89
|
-
if (hasDockerEnv) {
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
// Ignore errors
|
|
95
|
-
}
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Create a backup of the current installation
|
|
100
|
-
*/
|
|
101
|
-
async createBackup(version) {
|
|
102
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
103
|
-
const backupName = `backup-${timestamp}`;
|
|
104
|
-
const backupPath = path.join(this.backupsDir, backupName);
|
|
105
|
-
// Ensure backups directory exists
|
|
106
|
-
await fs.mkdir(this.backupsDir, { recursive: true });
|
|
107
|
-
// Use git to create a clean copy (respecting .gitignore)
|
|
108
|
-
await safeExec('git', [
|
|
109
|
-
'archive',
|
|
110
|
-
'--format=tar',
|
|
111
|
-
'HEAD'
|
|
112
|
-
], { cwd: this.rootDir }).then(async ({ stdout }) => {
|
|
113
|
-
// Create backup directory
|
|
114
|
-
await fs.mkdir(backupPath, { recursive: true });
|
|
115
|
-
// Extract tar to backup directory
|
|
116
|
-
const tarPath = path.join(backupPath, 'archive.tar');
|
|
117
|
-
await fs.writeFile(tarPath, stdout);
|
|
118
|
-
// Extract using tar command
|
|
119
|
-
await safeExec('tar', ['-xf', 'archive.tar'], { cwd: backupPath });
|
|
120
|
-
await fs.unlink(tarPath);
|
|
121
|
-
});
|
|
122
|
-
// Also backup node_modules if it exists
|
|
123
|
-
const nodeModulesPath = path.join(this.rootDir, 'node_modules');
|
|
124
|
-
try {
|
|
125
|
-
await fs.access(nodeModulesPath);
|
|
126
|
-
const destNodeModules = path.join(backupPath, 'node_modules');
|
|
127
|
-
// Use cross-platform file copy instead of Unix-specific cp -r
|
|
128
|
-
await FileOperations.copyDirectory(nodeModulesPath, destNodeModules, {
|
|
129
|
-
excludePatterns: ['.bin', '.cache'],
|
|
130
|
-
onProgress: (copied, total) => {
|
|
131
|
-
if (copied % 100 === 0) {
|
|
132
|
-
logger.debug(`[BackupManager] Backing up node_modules: ${copied}/${total} files`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
// node_modules doesn't exist or copy failed, that's okay
|
|
139
|
-
logger.debug('[BackupManager] Could not backup node_modules:', error);
|
|
140
|
-
}
|
|
141
|
-
// Backup all persona files (including user-created ones not in git)
|
|
142
|
-
const personasDir = path.join(this.rootDir, 'personas');
|
|
143
|
-
const backupPersonasDir = path.join(backupPath, 'personas');
|
|
144
|
-
try {
|
|
145
|
-
await fs.access(personasDir);
|
|
146
|
-
await fs.mkdir(backupPersonasDir, { recursive: true });
|
|
147
|
-
const personaFiles = await fs.readdir(personasDir);
|
|
148
|
-
for (const file of personaFiles) {
|
|
149
|
-
if (file.endsWith('.md')) {
|
|
150
|
-
const sourcePath = path.join(personasDir, file);
|
|
151
|
-
const destPath = path.join(backupPersonasDir, file);
|
|
152
|
-
// Copy the file, overwriting if it already exists from git archive
|
|
153
|
-
await fs.copyFile(sourcePath, destPath);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
// Log warning but don't fail the backup
|
|
159
|
-
logger.warn('Could not backup all personas:', error);
|
|
160
|
-
}
|
|
161
|
-
// Save backup metadata
|
|
162
|
-
const metadata = {
|
|
163
|
-
timestamp,
|
|
164
|
-
version,
|
|
165
|
-
createdAt: new Date().toISOString()
|
|
166
|
-
};
|
|
167
|
-
await fs.writeFile(path.join(backupPath, 'backup-metadata.json'), JSON.stringify(metadata, null, 2));
|
|
168
|
-
return {
|
|
169
|
-
path: backupPath,
|
|
170
|
-
timestamp,
|
|
171
|
-
version
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Create a backup specifically for npm installations
|
|
176
|
-
*/
|
|
177
|
-
async createNpmBackup(npmGlobalPath, version) {
|
|
178
|
-
try {
|
|
179
|
-
// Create npm-specific backup directory
|
|
180
|
-
const npmBackupsDir = path.join(path.dirname(this.backupsDir), '.dollhouse', 'backups', 'npm');
|
|
181
|
-
await fs.mkdir(npmBackupsDir, { recursive: true });
|
|
182
|
-
// Create timestamp-based backup directory
|
|
183
|
-
const timestamp = new Date().toISOString().replace(/:/g, '-').replace(/\./g, '-');
|
|
184
|
-
const backupName = `npm-backup-${timestamp}`;
|
|
185
|
-
const backupPath = path.join(npmBackupsDir, backupName);
|
|
186
|
-
logger.info(`[BackupManager] Creating npm backup at: ${backupPath}`);
|
|
187
|
-
// Create backup directory
|
|
188
|
-
await fs.mkdir(backupPath, { recursive: true });
|
|
189
|
-
// Copy the npm package directory
|
|
190
|
-
await this.copyDirectory(npmGlobalPath, path.join(backupPath, 'package'));
|
|
191
|
-
// Save backup metadata
|
|
192
|
-
const metadata = {
|
|
193
|
-
timestamp,
|
|
194
|
-
version,
|
|
195
|
-
npmGlobalPath,
|
|
196
|
-
installationType: 'npm',
|
|
197
|
-
createdAt: new Date().toISOString()
|
|
198
|
-
};
|
|
199
|
-
await fs.writeFile(path.join(backupPath, 'backup-metadata.json'), JSON.stringify(metadata, null, 2));
|
|
200
|
-
// Update manifest
|
|
201
|
-
await this.updateNpmBackupManifest(npmBackupsDir, {
|
|
202
|
-
backupName,
|
|
203
|
-
timestamp,
|
|
204
|
-
version,
|
|
205
|
-
path: backupPath
|
|
206
|
-
});
|
|
207
|
-
// Cleanup old npm backups (keep last 3)
|
|
208
|
-
await this.cleanupOldNpmBackups(npmBackupsDir, 3);
|
|
209
|
-
return backupPath;
|
|
210
|
-
}
|
|
211
|
-
catch (error) {
|
|
212
|
-
logger.error('[BackupManager] Failed to create npm backup:', error);
|
|
213
|
-
throw error;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Copy directory recursively with progress reporting
|
|
218
|
-
* @deprecated Use FileOperations.copyDirectory instead
|
|
219
|
-
*/
|
|
220
|
-
async copyDirectory(src, dest) {
|
|
221
|
-
await FileOperations.copyDirectory(src, dest, {
|
|
222
|
-
excludePatterns: ['.git'],
|
|
223
|
-
onProgress: (copied, total, file) => {
|
|
224
|
-
if (copied % 50 === 0) {
|
|
225
|
-
logger.debug(`[BackupManager] Copying: ${copied}/${total} files`);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Update npm backup manifest
|
|
232
|
-
*/
|
|
233
|
-
async updateNpmBackupManifest(npmBackupsDir, backupInfo) {
|
|
234
|
-
const manifestPath = path.join(npmBackupsDir, 'manifest.json');
|
|
235
|
-
let manifest = { backups: [] };
|
|
236
|
-
try {
|
|
237
|
-
const content = await fs.readFile(manifestPath, 'utf-8');
|
|
238
|
-
manifest = JSON.parse(content);
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
// File doesn't exist or is invalid, use default
|
|
242
|
-
}
|
|
243
|
-
// Add new backup to beginning of list
|
|
244
|
-
manifest.backups.unshift(backupInfo);
|
|
245
|
-
// Keep only last 10 entries in manifest
|
|
246
|
-
manifest.backups = manifest.backups.slice(0, 10);
|
|
247
|
-
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Clean up old npm backups
|
|
251
|
-
*/
|
|
252
|
-
async cleanupOldNpmBackups(npmBackupsDir, keepCount) {
|
|
253
|
-
try {
|
|
254
|
-
const entries = await fs.readdir(npmBackupsDir, { withFileTypes: true });
|
|
255
|
-
const backupDirs = entries
|
|
256
|
-
.filter(e => e.isDirectory() && e.name.startsWith('npm-backup-'))
|
|
257
|
-
.map(e => e.name)
|
|
258
|
-
.sort()
|
|
259
|
-
.reverse();
|
|
260
|
-
// Remove old backups
|
|
261
|
-
const toRemove = backupDirs.slice(keepCount);
|
|
262
|
-
for (const dir of toRemove) {
|
|
263
|
-
const dirPath = path.join(npmBackupsDir, dir);
|
|
264
|
-
logger.info(`[BackupManager] Removing old npm backup: ${dir}`);
|
|
265
|
-
await fs.rm(dirPath, { recursive: true, force: true });
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
catch (error) {
|
|
269
|
-
logger.warn('[BackupManager] Failed to cleanup old npm backups:', error);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* List available backups
|
|
274
|
-
*/
|
|
275
|
-
async listBackups() {
|
|
276
|
-
try {
|
|
277
|
-
const entries = await fs.readdir(this.backupsDir, { withFileTypes: true });
|
|
278
|
-
const backups = [];
|
|
279
|
-
for (const entry of entries) {
|
|
280
|
-
if (entry.isDirectory() && entry.name.startsWith('backup-')) {
|
|
281
|
-
const backupPath = path.join(this.backupsDir, entry.name);
|
|
282
|
-
const timestamp = entry.name.replace('backup-', '');
|
|
283
|
-
// Try to read metadata
|
|
284
|
-
let version;
|
|
285
|
-
try {
|
|
286
|
-
const metadataPath = path.join(backupPath, 'backup-metadata.json');
|
|
287
|
-
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
288
|
-
version = metadata.version;
|
|
289
|
-
}
|
|
290
|
-
catch {
|
|
291
|
-
// No metadata file, that's okay
|
|
292
|
-
}
|
|
293
|
-
backups.push({
|
|
294
|
-
path: backupPath,
|
|
295
|
-
timestamp,
|
|
296
|
-
version
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
// Sort by timestamp descending (newest first)
|
|
301
|
-
return backups.sort((a, b) => b.timestamp.localeCompare(a.timestamp));
|
|
302
|
-
}
|
|
303
|
-
catch {
|
|
304
|
-
return [];
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Get the most recent backup
|
|
309
|
-
*/
|
|
310
|
-
async getLatestBackup() {
|
|
311
|
-
const backups = await this.listBackups();
|
|
312
|
-
return backups.length > 0 ? backups[0] : null;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Restore from a backup
|
|
316
|
-
*/
|
|
317
|
-
async restoreBackup(backupPath) {
|
|
318
|
-
// Verify backup exists
|
|
319
|
-
try {
|
|
320
|
-
await fs.access(backupPath);
|
|
321
|
-
}
|
|
322
|
-
catch {
|
|
323
|
-
throw new Error(`Backup not found: ${backupPath}`);
|
|
324
|
-
}
|
|
325
|
-
// Create a temporary directory for the current state
|
|
326
|
-
const tempDir = path.join(this.backupsDir, 'temp-current');
|
|
327
|
-
await fs.mkdir(tempDir, { recursive: true });
|
|
328
|
-
// Move current files to temp (except .git and node_modules)
|
|
329
|
-
const entries = await fs.readdir(this.rootDir);
|
|
330
|
-
for (const entry of entries) {
|
|
331
|
-
if (entry !== '.git' && entry !== 'node_modules' && entry !== 'dist') {
|
|
332
|
-
const sourcePath = path.join(this.rootDir, entry);
|
|
333
|
-
const destPath = path.join(tempDir, entry);
|
|
334
|
-
await fs.rename(sourcePath, destPath);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
// Copy backup files to root
|
|
338
|
-
const backupEntries = await fs.readdir(backupPath);
|
|
339
|
-
for (const entry of backupEntries) {
|
|
340
|
-
if (entry !== 'backup-metadata.json' && entry !== '.git') {
|
|
341
|
-
const sourcePath = path.join(backupPath, entry);
|
|
342
|
-
const destPath = path.join(this.rootDir, entry);
|
|
343
|
-
await safeExec('cp', ['-r', sourcePath, destPath]);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
// Clean up temp directory
|
|
347
|
-
await fs.rm(tempDir, { recursive: true, force: true });
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Clean up old backups (keep the 5 most recent)
|
|
351
|
-
*/
|
|
352
|
-
async cleanupOldBackups(keepCount = 5) {
|
|
353
|
-
const backups = await this.listBackups();
|
|
354
|
-
let deletedCount = 0;
|
|
355
|
-
if (backups.length > keepCount) {
|
|
356
|
-
const backupsToDelete = backups.slice(keepCount);
|
|
357
|
-
for (const backup of backupsToDelete) {
|
|
358
|
-
try {
|
|
359
|
-
await fs.rm(backup.path, { recursive: true, force: true });
|
|
360
|
-
deletedCount++;
|
|
361
|
-
}
|
|
362
|
-
catch (error) {
|
|
363
|
-
logger.error(`Failed to delete backup ${backup.path}:`, error);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return deletedCount;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmFja3VwTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91cGRhdGUvQmFja3VwTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxNQUFNLE1BQU0sSUFBSSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBUTVELE1BQU0sT0FBTyxhQUFhO0lBQ2hCLE9BQU8sQ0FBUztJQUNoQixVQUFVLENBQVM7SUFFM0IsWUFBWSxPQUFnQjtRQUMxQix5Q0FBeUM7UUFDekMsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLHVDQUF1QztZQUN2QyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFDckUsQ0FBQztZQUNELDhCQUE4QjtZQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUM5QixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNILENBQUM7UUFFRCx1REFBdUQ7UUFDdkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRXhDLGdGQUFnRjtRQUNoRixvRUFBb0U7UUFDcEUsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUs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Q0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNYW5hZ2UgYmFja3VwcyBkdXJpbmcgdXBkYXRlc1xuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIGZzU3luYyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgc2FmZUV4ZWMgfSBmcm9tICcuLi91dGlscy9naXQuanMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IEZpbGVPcGVyYXRpb25zIH0gZnJvbSAnLi4vdXRpbHMvZmlsZU9wZXJhdGlvbnMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2t1cEluZm8ge1xuICBwYXRoOiBzdHJpbmc7XG4gIHRpbWVzdGFtcDogc3RyaW5nO1xuICB2ZXJzaW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgQmFja3VwTWFuYWdlciB7XG4gIHByaXZhdGUgcm9vdERpcjogc3RyaW5nO1xuICBwcml2YXRlIGJhY2t1cHNEaXI6IHN0cmluZztcbiAgXG4gIGNvbnN0cnVjdG9yKHJvb3REaXI/OiBzdHJpbmcpIHtcbiAgICAvLyBWYWxpZGF0ZSByb290RGlyIHBhcmFtZXRlciBpZiBwcm92aWRlZFxuICAgIGlmIChyb290RGlyKSB7XG4gICAgICAvLyBQcmV2ZW50IHBhdGggdHJhdmVyc2FsIGF0dGFja3MgZmlyc3RcbiAgICAgIGlmIChyb290RGlyLmluY2x1ZGVzKCcuLi8nKSB8fCByb290RGlyLmluY2x1ZGVzKCcuLlxcXFwnKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jvb3REaXIgY2Fubm90IGNvbnRhaW4gcGF0aCB0cmF2ZXJzYWwgc2VxdWVuY2VzJyk7XG4gICAgICB9XG4gICAgICAvLyBUaGVuIGNoZWNrIGlmIGl0J3MgYWJzb2x1dGVcbiAgICAgIGlmICghcGF0aC5pc0Fic29sdXRlKHJvb3REaXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncm9vdERpciBtdXN0IGJlIGFuIGFic29sdXRlIHBhdGgnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgLy8gQWxsb3cgb3ZlcnJpZGUgZm9yIHRlc3RpbmcsIGRlZmF1bHQgdG8gcHJvY2Vzcy5jd2QoKVxuICAgIHRoaXMucm9vdERpciA9IHJvb3REaXIgfHwgcHJvY2Vzcy5jd2QoKTtcbiAgICBcbiAgICAvLyBTYWZldHkgY2hlY2s6IERvbid0IGFsbG93IG9wZXJhdGlvbnMgb24gZGlyZWN0b3JpZXMgY29udGFpbmluZyBjcml0aWNhbCBmaWxlc1xuICAgIC8vIFRoaXMgcHJldmVudHMgYWNjaWRlbnRhbCBkZWxldGlvbiBvZiB0aGUgYWN0dWFsIHByb2plY3QgZGlyZWN0b3J5XG4gICAgaWYgKHRoaXMuaGFzUHJvZHVjdGlvbkZpbGVzKCkgJiYgIXRoaXMuaXNTYWZlVGVzdERpcmVjdG9yeSgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JhY2t1cE1hbmFnZXIgY2Fubm90IG9wZXJhdGUgb24gcHJvZHVjdGlvbiBkaXJlY3RvcnkuIFBhc3MgYSBzYWZlIHRlc3QgZGlyZWN0b3J5IHRvIHRoZSBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgXG4gICAgdGhpcy5iYWNrdXBzRGlyID0gcGF0aC5qb2luKHRoaXMucm9vdERpciwgXCIuLlwiLCBcImRvbGxob3VzZW1jcC1iYWNrdXBzXCIpO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGRpcmVjdG9yeSBjb250YWlucyBwcm9kdWN0aW9uIGZpbGVzXG4gICAqL1xuICBwcml2YXRlIGhhc1Byb2R1Y3Rpb25GaWxlcygpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcHJvZHVjdGlvbkluZGljYXRvcnMgPSBbXG4gICAgICAgICdwYWNrYWdlLmpzb24nLFxuICAgICAgICAndHNjb25maWcuanNvbicsXG4gICAgICAgICcuZ2l0JyxcbiAgICAgICAgJ3NyYycsXG4gICAgICAgICdMSUNFTlNFJ1xuICAgICAgXTtcbiAgICAgIFxuICAgICAgY29uc3QgZmlsZXMgPSBmc1N5bmMucmVhZGRpclN5bmModGhpcy5yb290RGlyKTtcbiAgICAgIGNvbnN0IGhhc1Byb2R1Y3Rpb25GaWxlID0gcHJvZHVjdGlvbkluZGljYXRvcnMuc29tZShpbmRpY2F0b3IgPT4gXG4gICAgICAgIGZpbGVzLmluY2x1ZGVzKGluZGljYXRvcilcbiAgICAgICk7XG4gICAgICBcbiAgICAgIC8vIEFkZGl0aW9uYWwgY2hlY2s6IGlmIHBhY2thZ2UuanNvbiBleGlzdHMsIGNoZWNrIGlmIGl0J3MgYSByZWFsIHByb2plY3RcbiAgICAgIGlmIChoYXNQcm9kdWN0aW9uRmlsZSAmJiBmaWxlcy5pbmNsdWRlcygncGFja2FnZS5qc29uJykpIHtcbiAgICAgICAgY29uc3QgcGFja2FnZUpzb25QYXRoID0gcGF0aC5qb2luKHRoaXMucm9vdERpciwgJ3BhY2thZ2UuanNvbicpO1xuICAgICAgICBjb25zdCBwYWNrYWdlSnNvbiA9IEpTT04ucGFyc2UoZnNTeW5jLnJlYWRGaWxlU3luYyhwYWNrYWdlSnNvblBhdGgsICd1dGYtOCcpKTtcbiAgICAgICAgLy8gSWYgaXQgaGFzIGEgbmFtZSBhbmQgZGVwZW5kZW5jaWVzLCBpdCdzIGxpa2VseSBhIHJlYWwgcHJvamVjdFxuICAgICAgICByZXR1cm4gISEocGFja2FnZUpzb24ubmFtZSAmJiBwYWNrYWdlSnNvbi5kZXBlbmRlbmNpZXMpO1xuICAgICAgfVxuICAgICAgXG4gICAgICByZXR1cm4gaGFzUHJvZHVjdGlvbkZpbGU7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBJZiB3ZSBjYW4ndCByZWFkIHRoZSBkaXJlY3RvcnksIGFzc3VtZSBpdCdzIHNhZmVcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGlzIGFwcGVhcnMgdG8gYmUgYSBzYWZlIHRlc3QgZGlyZWN0b3J5XG4gICAqL1xuICBwcml2YXRlIGlzU2FmZVRlc3REaXJlY3RvcnkoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgc2FmZVBhdGhzID0gWyd0ZXN0JywgJ3RtcCcsICd0ZW1wJywgJy50ZXN0JywgJ19fdGVzdF9fJ107XG4gICAgY29uc3QgZGlyUGF0aCA9IHRoaXMucm9vdERpci50b0xvd2VyQ2FzZSgpO1xuICAgIFxuICAgIC8vIENoZWNrIGlmIHJ1bm5pbmcgaW4gRG9ja2VyIGNvbnRhaW5lclxuICAgIGlmICh0aGlzLmlzRG9ja2VyRW52aXJvbm1lbnQoKSkge1xuICAgICAgcmV0dXJuIHRydWU7IC8vIERvY2tlciBjb250YWluZXJzIGFyZSBpbW11dGFibGUsIHVwZGF0ZXMgZG9uJ3QgYXBwbHlcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHNhZmVQYXRocy5zb21lKHNhZmUgPT4gZGlyUGF0aC5pbmNsdWRlcyhzYWZlKSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDaGVjayBpZiBydW5uaW5nIGluIGEgRG9ja2VyIGNvbnRhaW5lclxuICAgKi9cbiAgcHJpdmF0ZSBpc0RvY2tlckVudmlyb25tZW50KCk6IGJvb2xlYW4ge1xuICAgIC8vIENoZWNrIGNvbW1vbiBEb2NrZXIgaW5kaWNhdG9yc1xuICAgIGlmIChwcm9jZXNzLmVudi5ET0xMSE9VU0VfRElTQUJMRV9VUERBVEVTID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBcbiAgICAvLyBDaGVjayBpZiBydW5uaW5nIGZyb20gL2FwcCBkaXJlY3RvcnkgKGNvbW1vbiBEb2NrZXIgcHJhY3RpY2UpXG4gICAgaWYgKHRoaXMucm9vdERpciA9PT0gJy9hcHAnKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgZm9yIERvY2tlci1zcGVjaWZpYyBmaWxlc1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBoYXNEb2NrZXJFbnYgPSBmc1N5bmMuZXhpc3RzU3luYygnLy5kb2NrZXJlbnYnKTtcbiAgICAgIGlmIChoYXNEb2NrZXJFbnYpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBJZ25vcmUgZXJyb3JzXG4gICAgfVxuICAgIFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIENyZWF0ZSBhIGJhY2t1cCBvZiB0aGUgY3VycmVudCBpbnN0YWxsYXRpb25cbiAgICovXG4gIGFzeW5jIGNyZWF0ZUJhY2t1cCh2ZXJzaW9uPzogc3RyaW5nKTogUHJvbWlzZTxCYWNrdXBJbmZvPiB7XG4gICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6Ll0vZywgJy0nKTtcbiAgICBjb25zdCBiYWNrdXBOYW1lID0gYGJhY2t1cC0ke3RpbWVzdGFtcH1gO1xuICAgIGNvbnN0IGJhY2t1cFBhdGggPSBwYXRoLmpvaW4odGhpcy5iYWNrdXBzRGlyLCBiYWNrdXBOYW1lKTtcbiAgICBcbiAgICAvLyBFbnN1cmUgYmFja3VwcyBkaXJlY3RvcnkgZXhpc3RzXG4gICAgYXdhaXQgZnMubWtkaXIodGhpcy5iYWNrdXBzRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBcbiAgICAvLyBVc2UgZ2l0IHRvIGNyZWF0ZSBhIGNsZWFuIGNvcHkgKHJlc3BlY3RpbmcgLmdpdGlnbm9yZSlcbiAgICBhd2FpdCBzYWZlRXhlYygnZ2l0JywgW1xuICAgICAgJ2FyY2hpdmUnLFxuICAgICAgJy0tZm9ybWF0PXRhcicsXG4gICAgICAnSEVBRCdcbiAgICBdLCB7IGN3ZDogdGhpcy5yb290RGlyIH0pLnRoZW4oYXN5bmMgKHsgc3Rkb3V0IH0pID0+IHtcbiAgICAgIC8vIENyZWF0ZSBiYWNrdXAgZGlyZWN0b3J5XG4gICAgICBhd2FpdCBmcy5ta2RpcihiYWNrdXBQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIFxuICAgICAgLy8gRXh0cmFjdCB0YXIgdG8gYmFja3VwIGRpcmVjdG9yeVxuICAgICAgY29uc3QgdGFyUGF0aCA9IHBhdGguam9pbihiYWNrdXBQYXRoLCAnYXJjaGl2ZS50YXInKTtcbiAgICAgIGF3YWl0IGZzLndyaXRlRmlsZSh0YXJQYXRoLCBzdGRvdXQpO1xuICAgICAgXG4gICAgICAvLyBFeHRyYWN0IHVzaW5nIHRhciBjb21tYW5kXG4gICAgICBhd2FpdCBzYWZlRXhlYygndGFyJywgWycteGYnLCAnYXJjaGl2ZS50YXInXSwgeyBjd2Q6IGJhY2t1cFBhdGggfSk7XG4gICAgICBhd2FpdCBmcy51bmxpbmsodGFyUGF0aCk7XG4gICAgfSk7XG4gICAgXG4gICAgLy8gQWxzbyBiYWNrdXAgbm9kZV9tb2R1bGVzIGlmIGl0IGV4aXN0c1xuICAgIGNvbnN0IG5vZGVNb2R1bGVzUGF0aCA9IHBhdGguam9pbih0aGlzLnJvb3REaXIsICdub2RlX21vZHVsZXMnKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMuYWNjZXNzKG5vZGVNb2R1bGVzUGF0aCk7XG4gICAgICBjb25zdCBkZXN0Tm9kZU1vZHVsZXMgPSBwYXRoLmpvaW4oYmFja3VwUGF0aCwgJ25vZGVfbW9kdWxlcycpO1xuICAgICAgXG4gICAgICAvLyBVc2UgY3Jvc3MtcGxhdGZvcm0gZmlsZSBjb3B5IGluc3RlYWQgb2YgVW5peC1zcGVjaWZpYyBjcCAtclxuICAgICAgYXdhaXQgRmlsZU9wZXJhdGlvbnMuY29weURpcmVjdG9yeShub2RlTW9kdWxlc1BhdGgsIGRlc3ROb2RlTW9kdWxlcywge1xuICAgICAgICBleGNsdWRlUGF0dGVybnM6IFsnLmJpbicsICcuY2FjaGUnXSxcbiAgICAgICAgb25Qcm9ncmVzczogKGNvcGllZCwgdG90YWwpID0+IHtcbiAgICAgICAgICBpZiAoY29waWVkICUgMTAwID09PSAwKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYFtCYWNrdXBNYW5hZ2VyXSBCYWNraW5nIHVwIG5vZGVfbW9kdWxlczogJHtjb3BpZWR9LyR7dG90YWx9IGZpbGVzYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gbm9kZV9tb2R1bGVzIGRvZXNuJ3QgZXhpc3Qgb3IgY29weSBmYWlsZWQsIHRoYXQncyBva2F5XG4gICAgICBsb2dnZXIuZGVidWcoJ1tCYWNrdXBNYW5hZ2VyXSBDb3VsZCBub3QgYmFja3VwIG5vZGVfbW9kdWxlczonLCBlcnJvcik7XG4gICAgfVxuICAgIFxuICAgIC8vIEJhY2t1cCBhbGwgcGVyc29uYSBmaWxlcyAoaW5jbHVkaW5nIHVzZXItY3JlYXRlZCBvbmVzIG5vdCBpbiBnaXQpXG4gICAgY29uc3QgcGVyc29uYXNEaXIgPSBwYXRoLmpvaW4odGhpcy5yb290RGlyLCAncGVyc29uYXMnKTtcbiAgICBjb25zdCBiYWNrdXBQZXJzb25hc0RpciA9IHBhdGguam9pbihiYWNrdXBQYXRoLCAncGVyc29uYXMnKTtcbiAgICBcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMuYWNjZXNzKHBlcnNvbmFzRGlyKTtcbiAgICAgIGF3YWl0IGZzLm1rZGlyKGJhY2t1cFBlcnNvbmFzRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIFxuICAgICAgY29uc3QgcGVyc29uYUZpbGVzID0gYXdhaXQgZnMucmVhZGRpcihwZXJzb25hc0Rpcik7XG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcGVyc29uYUZpbGVzKSB7XG4gICAgICAgIGlmIChmaWxlLmVuZHNXaXRoKCcubWQnKSkge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZVBhdGggPSBwYXRoLmpvaW4ocGVyc29uYXNEaXIsIGZpbGUpO1xuICAgICAgICAgIGNvbnN0IGRlc3RQYXRoID0gcGF0aC5qb2luKGJhY2t1cFBlcnNvbmFzRGlyLCBmaWxlKTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBDb3B5IHRoZSBmaWxlLCBvdmVyd3JpdGluZyBpZiBpdCBhbHJlYWR5IGV4aXN0cyBmcm9tIGdpdCBhcmNoaXZlXG4gICAgICAgICAgYXdhaXQgZnMuY29weUZpbGUoc291cmNlUGF0aCwgZGVzdFBhdGgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIExvZyB3YXJuaW5nIGJ1dCBkb24ndCBmYWlsIHRoZSBiYWNrdXBcbiAgICAgIGxvZ2dlci53YXJuKCdDb3VsZCBub3QgYmFja3VwIGFsbCBwZXJzb25hczonLCBlcnJvcik7XG4gICAgfVxuICAgIFxuICAgIC8vIFNhdmUgYmFja3VwIG1ldGFkYXRhXG4gICAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgICB0aW1lc3RhbXAsXG4gICAgICB2ZXJzaW9uLFxuICAgICAgY3JlYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcbiAgICB9O1xuICAgIGF3YWl0IGZzLndyaXRlRmlsZShcbiAgICAgIHBhdGguam9pbihiYWNrdXBQYXRoLCAnYmFja3VwLW1ldGFkYXRhLmpzb24nKSxcbiAgICAgIEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhLCBudWxsLCAyKVxuICAgICk7XG4gICAgXG4gICAgcmV0dXJuIHtcbiAgICAgIHBhdGg6IGJhY2t1cFBhdGgsXG4gICAgICB0aW1lc3RhbXAsXG4gICAgICB2ZXJzaW9uXG4gICAgfTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIENyZWF0ZSBhIGJhY2t1cCBzcGVjaWZpY2FsbHkgZm9yIG5wbSBpbnN0YWxsYXRpb25zXG4gICAqL1xuICBhc3luYyBjcmVhdGVOcG1CYWNrdXAobnBtR2xvYmFsUGF0aDogc3RyaW5nLCB2ZXJzaW9uPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICB0cnkge1xuICAgICAgLy8gQ3JlYXRlIG5wbS1zcGVjaWZpYyBiYWNrdXAgZGlyZWN0b3J5XG4gICAgICBjb25zdCBucG1CYWNrdXBzRGlyID0gcGF0aC5qb2luKHBhdGguZGlybmFtZSh0aGlzLmJhY2t1cHNEaXIpLCAnLmRvbGxob3VzZScsICdiYWNrdXBzJywgJ25wbScpO1xuICAgICAgYXdhaXQgZnMubWtkaXIobnBtQmFja3Vwc0RpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBcbiAgICAgIC8vIENyZWF0ZSB0aW1lc3RhbXAtYmFzZWQgYmFja3VwIGRpcmVjdG9yeVxuICAgICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoLzovZywgJy0nKS5yZXBsYWNlKC9cXC4vZywgJy0nKTtcbiAgICAgIGNvbnN0IGJhY2t1cE5hbWUgPSBgbnBtLWJhY2t1cC0ke3RpbWVzdGFtcH1gO1xuICAgICAgY29uc3QgYmFja3VwUGF0aCA9IHBhdGguam9pbihucG1CYWNrdXBzRGlyLCBiYWNrdXBOYW1lKTtcbiAgICAgIFxuICAgICAgbG9nZ2VyLmluZm8oYFtCYWNrdXBNYW5hZ2VyXSBDcmVhdGluZyBucG0gYmFja3VwIGF0OiAke2JhY2t1cFBhdGh9YCk7XG4gICAgICBcbiAgICAgIC8vIENyZWF0ZSBiYWNrdXAgZGlyZWN0b3J5XG4gICAgICBhd2FpdCBmcy5ta2RpcihiYWNrdXBQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIFxuICAgICAgLy8gQ29weSB0aGUgbnBtIHBhY2thZ2UgZGlyZWN0b3J5XG4gICAgICBhd2FpdCB0aGlzLmNvcHlEaXJlY3RvcnkobnBtR2xvYmFsUGF0aCwgcGF0aC5qb2luKGJhY2t1cFBhdGgsICdwYWNrYWdlJykpO1xuICAgICAgXG4gICAgICAvLyBTYXZlIGJhY2t1cCBtZXRhZGF0YVxuICAgICAgY29uc3QgbWV0YWRhdGEgPSB7XG4gICAgICAgIHRpbWVzdGFtcCxcbiAgICAgICAgdmVyc2lvbixcbiAgICAgICAgbnBtR2xvYmFsUGF0aCxcbiAgICAgICAgaW5zdGFsbGF0aW9uVHlwZTogJ25wbScsXG4gICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gICAgICB9O1xuICAgICAgXG4gICAgICBhd2FpdCBmcy53cml0ZUZpbGUoXG4gICAgICAgIHBhdGguam9pbihiYWNrdXBQYXRoLCAnYmFja3VwLW1ldGFkYXRhLmpzb24nKSxcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEsIG51bGwsIDIpXG4gICAgICApO1xuICAgICAgXG4gICAgICAvLyBVcGRhdGUgbWFuaWZlc3RcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlTnBtQmFja3VwTWFuaWZlc3QobnBtQmFja3Vwc0Rpciwge1xuICAgICAgICBiYWNrdXBOYW1lLFxuICAgICAgICB0aW1lc3RhbXAsXG4gICAgICAgIHZlcnNpb24sXG4gICAgICAgIHBhdGg6IGJhY2t1cFBhdGhcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICAvLyBDbGVhbnVwIG9sZCBucG0gYmFja3VwcyAoa2VlcCBsYXN0IDMpXG4gICAgICBhd2FpdCB0aGlzLmNsZWFudXBPbGROcG1CYWNrdXBzKG5wbUJhY2t1cHNEaXIsIDMpO1xuICAgICAgXG4gICAgICByZXR1cm4gYmFja3VwUGF0aDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdbQmFja3VwTWFuYWdlcl0gRmFpbGVkIHRvIGNyZWF0ZSBucG0gYmFja3VwOicsIGVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIENvcHkgZGlyZWN0b3J5IHJlY3Vyc2l2ZWx5IHdpdGggcHJvZ3Jlc3MgcmVwb3J0aW5nXG4gICAqIEBkZXByZWNhdGVkIFVzZSBGaWxlT3BlcmF0aW9ucy5jb3B5RGlyZWN0b3J5IGluc3RlYWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY29weURpcmVjdG9yeShzcmM6IHN0cmluZywgZGVzdDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgRmlsZU9wZXJhdGlvbnMuY29weURpcmVjdG9yeShzcmMsIGRlc3QsIHtcbiAgICAgIGV4Y2x1ZGVQYXR0ZXJuczogWycuZ2l0J10sXG4gICAgICBvblByb2dyZXNzOiAoY29waWVkLCB0b3RhbCwgZmlsZSkgPT4ge1xuICAgICAgICBpZiAoY29waWVkICUgNTAgPT09IDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYFtCYWNrdXBNYW5hZ2VyXSBDb3B5aW5nOiAke2NvcGllZH0vJHt0b3RhbH0gZmlsZXNgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogVXBkYXRlIG5wbSBiYWNrdXAgbWFuaWZlc3RcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlTnBtQmFja3VwTWFuaWZlc3QobnBtQmFja3Vwc0Rpcjogc3RyaW5nLCBiYWNrdXBJbmZvOiB7XG4gICAgYmFja3VwTmFtZTogc3RyaW5nO1xuICAgIHRpbWVzdGFtcDogc3RyaW5nO1xuICAgIHZlcnNpb24/OiBzdHJpbmc7XG4gICAgcGF0aDogc3RyaW5nO1xuICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbWFuaWZlc3RQYXRoID0gcGF0aC5qb2luKG5wbUJhY2t1cHNEaXIsICdtYW5pZmVzdC5qc29uJyk7XG4gICAgXG4gICAgbGV0IG1hbmlmZXN0OiB7IGJhY2t1cHM6IEFycmF5PHtcbiAgICAgIGJhY2t1cE5hbWU6IHN0cmluZztcbiAgICAgIHRpbWVzdGFtcDogc3RyaW5nO1xuICAgICAgdmVyc2lvbj86IHN0cmluZztcbiAgICAgIHBhdGg6IHN0cmluZztcbiAgICB9PiB9ID0geyBiYWNrdXBzOiBbXSB9O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUobWFuaWZlc3RQYXRoLCAndXRmLTgnKTtcbiAgICAgIG1hbmlmZXN0ID0gSlNPTi5wYXJzZShjb250ZW50KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIEZpbGUgZG9lc24ndCBleGlzdCBvciBpcyBpbnZhbGlkLCB1c2UgZGVmYXVsdFxuICAgIH1cbiAgICBcbiAgICAvLyBBZGQgbmV3IGJhY2t1cCB0byBiZWdpbm5pbmcgb2YgbGlzdFxuICAgIG1hbmlmZXN0LmJhY2t1cHMudW5zaGlmdChiYWNrdXBJbmZvKTtcbiAgICBcbiAgICAvLyBLZWVwIG9ubHkgbGFzdCAxMCBlbnRyaWVzIGluIG1hbmlmZXN0XG4gICAgbWFuaWZlc3QuYmFja3VwcyA9IG1hbmlmZXN0LmJhY2t1cHMuc2xpY2UoMCwgMTApO1xuICAgIFxuICAgIGF3YWl0IGZzLndyaXRlRmlsZShtYW5pZmVzdFBhdGgsIEpTT04uc3RyaW5naWZ5KG1hbmlmZXN0LCBudWxsLCAyKSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDbGVhbiB1cCBvbGQgbnBtIGJhY2t1cHNcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgY2xlYW51cE9sZE5wbUJhY2t1cHMobnBtQmFja3Vwc0Rpcjogc3RyaW5nLCBrZWVwQ291bnQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZnMucmVhZGRpcihucG1CYWNrdXBzRGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgICBjb25zdCBiYWNrdXBEaXJzID0gZW50cmllc1xuICAgICAgICAuZmlsdGVyKGUgPT4gZS5pc0RpcmVjdG9yeSgpICYmIGUubmFtZS5zdGFydHNXaXRoKCducG0tYmFja3VwLScpKVxuICAgICAgICAubWFwKGUgPT4gZS5uYW1lKVxuICAgICAgICAuc29ydCgpXG4gICAgICAgIC5yZXZlcnNlKCk7XG4gICAgICBcbiAgICAgIC8vIFJlbW92ZSBvbGQgYmFja3Vwc1xuICAgICAgY29uc3QgdG9SZW1vdmUgPSBiYWNrdXBEaXJzLnNsaWNlKGtlZXBDb3VudCk7XG4gICAgICBmb3IgKGNvbnN0IGRpciBvZiB0b1JlbW92ZSkge1xuICAgICAgICBjb25zdCBkaXJQYXRoID0gcGF0aC5qb2luKG5wbUJhY2t1cHNEaXIsIGRpcik7XG4gICAgICAgIGxvZ2dlci5pbmZvKGBbQmFja3VwTWFuYWdlcl0gUmVtb3Zpbmcgb2xkIG5wbSBiYWNrdXA6ICR7ZGlyfWApO1xuICAgICAgICBhd2FpdCBmcy5ybShkaXJQYXRoLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdbQmFja3VwTWFuYWdlcl0gRmFpbGVkIHRvIGNsZWFudXAgb2xkIG5wbSBiYWNrdXBzOicsIGVycm9yKTtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBMaXN0IGF2YWlsYWJsZSBiYWNrdXBzXG4gICAqL1xuICBhc3luYyBsaXN0QmFja3VwcygpOiBQcm9taXNlPEJhY2t1cEluZm9bXT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZnMucmVhZGRpcih0aGlzLmJhY2t1cHNEaXIsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgICAgIGNvbnN0IGJhY2t1cHM6IEJhY2t1cEluZm9bXSA9IFtdO1xuICAgICAgXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkgJiYgZW50cnkubmFtZS5zdGFydHNXaXRoKCdiYWNrdXAtJykpIHtcbiAgICAgICAgICBjb25zdCBiYWNrdXBQYXRoID0gcGF0aC5qb2luKHRoaXMuYmFja3Vwc0RpciwgZW50cnkubmFtZSk7XG4gICAgICAgICAgY29uc3QgdGltZXN0YW1wID0gZW50cnkubmFtZS5yZXBsYWNlKCdiYWNrdXAtJywgJycpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIFRyeSB0byByZWFkIG1ldGFkYXRhXG4gICAgICAgICAgbGV0IHZlcnNpb246IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgbWV0YWRhdGFQYXRoID0gcGF0aC5qb2luKGJhY2t1cFBhdGgsICdiYWNrdXAtbWV0YWRhdGEuanNvbicpO1xuICAgICAgICAgICAgY29uc3QgbWV0YWRhdGEgPSBKU09OLnBhcnNlKGF3YWl0IGZzLnJlYWRGaWxlKG1ldGFkYXRhUGF0aCwgJ3V0Zi04JykpO1xuICAgICAgICAgICAgdmVyc2lvbiA9IG1ldGFkYXRhLnZlcnNpb247XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBObyBtZXRhZGF0YSBmaWxlLCB0aGF0J3Mgb2theVxuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICBiYWNrdXBzLnB1c2goe1xuICAgICAgICAgICAgcGF0aDogYmFja3VwUGF0aCxcbiAgICAgICAgICAgIHRpbWVzdGFtcCxcbiAgICAgICAgICAgIHZlcnNpb25cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBTb3J0IGJ5IHRpbWVzdGFtcCBkZXNjZW5kaW5nIChuZXdlc3QgZmlyc3QpXG4gICAgICByZXR1cm4gYmFja3Vwcy5zb3J0KChhLCBiKSA9PiBiLnRpbWVzdGFtcC5sb2NhbGVDb21wYXJlKGEudGltZXN0YW1wKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogR2V0IHRoZSBtb3N0IHJlY2VudCBiYWNrdXBcbiAgICovXG4gIGFzeW5jIGdldExhdGVzdEJhY2t1cCgpOiBQcm9taXNlPEJhY2t1cEluZm8gfCBudWxsPiB7XG4gICAgY29uc3QgYmFja3VwcyA9IGF3YWl0IHRoaXMubGlzdEJhY2t1cHMoKTtcbiAgICByZXR1cm4gYmFja3Vwcy5sZW5ndGggPiAwID8gYmFja3Vwc1swXSA6IG51bGw7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBSZXN0b3JlIGZyb20gYSBiYWNrdXBcbiAgICovXG4gIGFzeW5jIHJlc3RvcmVCYWNrdXAoYmFja3VwUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gVmVyaWZ5IGJhY2t1cCBleGlzdHNcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMuYWNjZXNzKGJhY2t1cFBhdGgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBCYWNrdXAgbm90IGZvdW5kOiAke2JhY2t1cFBhdGh9YCk7XG4gICAgfVxuICAgIFxuICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBkaXJlY3RvcnkgZm9yIHRoZSBjdXJyZW50IHN0YXRlXG4gICAgY29uc3QgdGVtcERpciA9IHBhdGguam9pbih0aGlzLmJhY2t1cHNEaXIsICd0ZW1wLWN1cnJlbnQnKTtcbiAgICBhd2FpdCBmcy5ta2Rpcih0ZW1wRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBcbiAgICAvLyBNb3ZlIGN1cnJlbnQgZmlsZXMgdG8gdGVtcCAoZXhjZXB0IC5naXQgYW5kIG5vZGVfbW9kdWxlcylcbiAgICBjb25zdCBlbnRyaWVzID0gYXdhaXQgZnMucmVhZGRpcih0aGlzLnJvb3REaXIpO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgaWYgKGVudHJ5ICE9PSAnLmdpdCcgJiYgZW50cnkgIT09ICdub2RlX21vZHVsZXMnICYmIGVudHJ5ICE9PSAnZGlzdCcpIHtcbiAgICAgICAgY29uc3Qgc291cmNlUGF0aCA9IHBhdGguam9pbih0aGlzLnJvb3REaXIsIGVudHJ5KTtcbiAgICAgICAgY29uc3QgZGVzdFBhdGggPSBwYXRoLmpvaW4odGVtcERpciwgZW50cnkpO1xuICAgICAgICBhd2FpdCBmcy5yZW5hbWUoc291cmNlUGF0aCwgZGVzdFBhdGgpO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBDb3B5IGJhY2t1cCBmaWxlcyB0byByb290XG4gICAgY29uc3QgYmFja3VwRW50cmllcyA9IGF3YWl0IGZzLnJlYWRkaXIoYmFja3VwUGF0aCk7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBiYWNrdXBFbnRyaWVzKSB7XG4gICAgICBpZiAoZW50cnkgIT09ICdiYWNrdXAtbWV0YWRhdGEuanNvbicgJiYgZW50cnkgIT09ICcuZ2l0Jykge1xuICAgICAgICBjb25zdCBzb3VyY2VQYXRoID0gcGF0aC5qb2luKGJhY2t1cFBhdGgsIGVudHJ5KTtcbiAgICAgICAgY29uc3QgZGVzdFBhdGggPSBwYXRoLmpvaW4odGhpcy5yb290RGlyLCBlbnRyeSk7XG4gICAgICAgIGF3YWl0IHNhZmVFeGVjKCdjcCcsIFsnLXInLCBzb3VyY2VQYXRoLCBkZXN0UGF0aF0pO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBDbGVhbiB1cCB0ZW1wIGRpcmVjdG9yeVxuICAgIGF3YWl0IGZzLnJtKHRlbXBEaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIENsZWFuIHVwIG9sZCBiYWNrdXBzIChrZWVwIHRoZSA1IG1vc3QgcmVjZW50KVxuICAgKi9cbiAgYXN5bmMgY2xlYW51cE9sZEJhY2t1cHMoa2VlcENvdW50OiBudW1iZXIgPSA1KTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBjb25zdCBiYWNrdXBzID0gYXdhaXQgdGhpcy5saXN0QmFja3VwcygpO1xuICAgIGxldCBkZWxldGVkQ291bnQgPSAwO1xuICAgIFxuICAgIGlmIChiYWNrdXBzLmxlbmd0aCA+IGtlZXBDb3VudCkge1xuICAgICAgY29uc3QgYmFja3Vwc1RvRGVsZXRlID0gYmFja3Vwcy5zbGljZShrZWVwQ291bnQpO1xuICAgICAgXG4gICAgICBmb3IgKGNvbnN0IGJhY2t1cCBvZiBiYWNrdXBzVG9EZWxldGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBmcy5ybShiYWNrdXAucGF0aCwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICAgIGRlbGV0ZWRDb3VudCsrO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcihgRmFpbGVkIHRvIGRlbGV0ZSBiYWNrdXAgJHtiYWNrdXAucGF0aH06YCwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBkZWxldGVkQ291bnQ7XG4gIH1cbn0iXX0=
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check and validate system dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { VersionManager } from './VersionManager.js';
|
|
5
|
-
export interface DependencyStatus {
|
|
6
|
-
git: {
|
|
7
|
-
installed: boolean;
|
|
8
|
-
version?: string;
|
|
9
|
-
valid?: boolean;
|
|
10
|
-
error?: string;
|
|
11
|
-
warning?: string;
|
|
12
|
-
};
|
|
13
|
-
npm: {
|
|
14
|
-
installed: boolean;
|
|
15
|
-
version?: string;
|
|
16
|
-
valid?: boolean;
|
|
17
|
-
error?: string;
|
|
18
|
-
warning?: string;
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
export declare class DependencyChecker {
|
|
22
|
-
private versionManager;
|
|
23
|
-
constructor(versionManager: VersionManager);
|
|
24
|
-
/**
|
|
25
|
-
* Check all system dependencies
|
|
26
|
-
*/
|
|
27
|
-
checkDependencies(): Promise<DependencyStatus>;
|
|
28
|
-
/**
|
|
29
|
-
* Check Git installation and version
|
|
30
|
-
*/
|
|
31
|
-
private checkGit;
|
|
32
|
-
/**
|
|
33
|
-
* Check npm installation and version
|
|
34
|
-
*/
|
|
35
|
-
private checkNpm;
|
|
36
|
-
/**
|
|
37
|
-
* Format dependency status for display
|
|
38
|
-
*/
|
|
39
|
-
formatDependencyStatus(status: DependencyStatus): string;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=DependencyChecker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DependencyChecker.d.ts","sourceRoot":"","sources":["../../src/update/DependencyChecker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE;QACH,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,GAAG,EAAE;QACH,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,cAAc,CAAiB;gBAE3B,cAAc,EAAE,cAAc;IAI1C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAYpD;;OAEG;YACW,QAAQ;IAiCtB;;OAEG;YACW,QAAQ;IAiCtB;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;CA4CzD"}
|