@dollhousemcp/mcp-server 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +54 -9
  2. package/dist/config/updateConfig.d.ts +84 -0
  3. package/dist/config/updateConfig.d.ts.map +1 -0
  4. package/dist/config/updateConfig.js +148 -0
  5. package/dist/generated/version.d.ts +9 -0
  6. package/dist/generated/version.d.ts.map +1 -0
  7. package/dist/generated/version.js +9 -0
  8. package/dist/index.d.ts +6 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +34 -6
  11. package/dist/portfolio/DefaultElementProvider.d.ts +78 -0
  12. package/dist/portfolio/DefaultElementProvider.d.ts.map +1 -0
  13. package/dist/portfolio/DefaultElementProvider.js +398 -0
  14. package/dist/portfolio/PortfolioManager.d.ts +7 -0
  15. package/dist/portfolio/PortfolioManager.d.ts.map +1 -1
  16. package/dist/portfolio/PortfolioManager.js +44 -3
  17. package/dist/security/commandValidator.d.ts.map +1 -1
  18. package/dist/security/commandValidator.js +5 -2
  19. package/dist/security/securityMonitor.d.ts +2 -1
  20. package/dist/security/securityMonitor.d.ts.map +1 -1
  21. package/dist/security/securityMonitor.js +1 -1
  22. package/dist/server/tools/UpdateTools.d.ts.map +1 -1
  23. package/dist/server/tools/UpdateTools.js +22 -1
  24. package/dist/server/types.d.ts +1 -0
  25. package/dist/server/types.d.ts.map +1 -1
  26. package/dist/server/types.js +1 -1
  27. package/dist/update/BackupManager.d.ts +17 -0
  28. package/dist/update/BackupManager.d.ts.map +1 -1
  29. package/dist/update/BackupManager.js +112 -3
  30. package/dist/update/UpdateManager.d.ts +19 -0
  31. package/dist/update/UpdateManager.d.ts.map +1 -1
  32. package/dist/update/UpdateManager.js +485 -15
  33. package/dist/update/VersionManager.d.ts +1 -1
  34. package/dist/update/VersionManager.d.ts.map +1 -1
  35. package/dist/update/VersionManager.js +62 -15
  36. package/dist/utils/fileOperations.d.ts +83 -0
  37. package/dist/utils/fileOperations.d.ts.map +1 -0
  38. package/dist/utils/fileOperations.js +291 -0
  39. package/dist/utils/installation.d.ts +30 -0
  40. package/dist/utils/installation.d.ts.map +1 -0
  41. package/dist/utils/installation.js +160 -0
  42. package/package.json +3 -1
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export declare class VersionManager {
5
5
  /**
6
- * Get current version from package.json
6
+ * Get current version from package.json or embedded version
7
7
  */
8
8
  getCurrentVersion(): Promise<string>;
9
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"VersionManager.d.ts","sourceRoot":"","sources":["../../src/update/VersionManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,qBAAa,cAAc;IACzB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAgC1C;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAgC3D;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BnE;;OAEG;IACH,yBAAyB,CACvB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EACvE,QAAQ,EAAE,MAAM,GACf;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAgCxD"}
1
+ {"version":3,"file":"VersionManager.d.ts","sourceRoot":"","sources":["../../src/update/VersionManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,qBAAa,cAAc;IACzB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IA4E1C;;;OAGG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAgC3D;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA2BnE;;OAEG;IACH,yBAAyB,CACvB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EACvE,QAAQ,EAAE,MAAM,GACf;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAgCxD"}
@@ -3,38 +3,85 @@
3
3
  */
4
4
  import * as fs from 'fs/promises';
5
5
  import * as path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import { logger } from '../utils/logger.js';
8
+ import { InstallationDetector } from '../utils/installation.js';
6
9
  export class VersionManager {
7
10
  /**
8
- * Get current version from package.json
11
+ * Get current version from package.json or embedded version
9
12
  */
10
13
  async getCurrentVersion() {
11
- // Use process.cwd() as a base, then search upward for package.json
14
+ // First, try to import the generated version file
15
+ try {
16
+ const { PACKAGE_VERSION } = await import('../generated/version.js');
17
+ if (PACKAGE_VERSION) {
18
+ logger.debug(`[VersionManager] Using embedded version: ${PACKAGE_VERSION}`);
19
+ return PACKAGE_VERSION;
20
+ }
21
+ }
22
+ catch (error) {
23
+ logger.debug('[VersionManager] No embedded version found, will search for package.json');
24
+ }
25
+ // Determine installation type
26
+ const installationType = InstallationDetector.getInstallationType();
27
+ // For npm installations, look relative to the module location
28
+ if (installationType === 'npm') {
29
+ const npmPath = InstallationDetector.getNpmGlobalPath();
30
+ if (npmPath) {
31
+ const packageJsonPath = path.join(npmPath, 'package.json');
32
+ try {
33
+ const packageContent = await fs.readFile(packageJsonPath, 'utf-8');
34
+ const packageData = JSON.parse(packageContent);
35
+ return packageData.version;
36
+ }
37
+ catch (error) {
38
+ logger.error('[VersionManager] Error reading package.json from npm path:', error);
39
+ }
40
+ }
41
+ }
42
+ // For git installations, search from current file location
43
+ if (installationType === 'git') {
44
+ const currentFileUrl = import.meta.url;
45
+ const currentFilePath = fileURLToPath(currentFileUrl);
46
+ let currentDir = path.dirname(currentFilePath);
47
+ // Search upward for package.json
48
+ for (let i = 0; i < 5; i++) {
49
+ const candidatePath = path.join(currentDir, 'package.json');
50
+ try {
51
+ await fs.access(candidatePath);
52
+ const packageContent = await fs.readFile(candidatePath, 'utf-8');
53
+ const packageData = JSON.parse(packageContent);
54
+ return packageData.version;
55
+ }
56
+ catch {
57
+ // File doesn't exist, try parent directory
58
+ const parentDir = path.dirname(currentDir);
59
+ if (parentDir === currentDir) {
60
+ break;
61
+ }
62
+ currentDir = parentDir;
63
+ }
64
+ }
65
+ }
66
+ // Last resort: try process.cwd() (original behavior)
12
67
  let currentDir = process.cwd();
13
- let packageJsonPath = null;
14
- // Search up to 5 levels for package.json
15
68
  for (let i = 0; i < 5; i++) {
16
69
  const candidatePath = path.join(currentDir, 'package.json');
17
70
  try {
18
71
  await fs.access(candidatePath);
19
- packageJsonPath = candidatePath;
20
- break;
72
+ const packageContent = await fs.readFile(candidatePath, 'utf-8');
73
+ const packageData = JSON.parse(packageContent);
74
+ return packageData.version;
21
75
  }
22
76
  catch {
23
- // File doesn't exist, try parent directory
24
77
  const parentDir = path.dirname(currentDir);
25
78
  if (parentDir === currentDir) {
26
- // We've reached the root
27
79
  break;
28
80
  }
29
81
  currentDir = parentDir;
30
82
  }
31
83
  }
32
- if (!packageJsonPath) {
33
- throw new Error('Could not find package.json in current directory or any parent directory');
34
- }
35
- const packageContent = await fs.readFile(packageJsonPath, 'utf-8');
36
- const packageData = JSON.parse(packageContent);
37
- return packageData.version;
84
+ throw new Error('Could not determine version. Please ensure you have a valid installation.');
38
85
  }
39
86
  /**
40
87
  * Enhanced semantic version comparison supporting pre-release versions
@@ -131,4 +178,4 @@ export class VersionManager {
131
178
  return { valid: true };
132
179
  }
133
180
  }
134
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVmVyc2lvbk1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXBkYXRlL1ZlcnNpb25NYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFFN0IsTUFBTSxPQUFPLGNBQWM7SUFDekI7O09BRUc7SUFDSCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLG1FQUFtRTtRQUNuRSxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxlQUFlLEdBQWtCLElBQUksQ0FBQztRQUUxQyx5Q0FBeUM7UUFDekMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzNCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQztnQkFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQy9CLGVBQWUsR0FBRyxhQUFhLENBQUM7Z0JBQ2hDLE1BQU07WUFDUixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLDJDQUEyQztnQkFDM0MsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFDM0MsSUFBSSxTQUFTLEtBQUssVUFBVSxFQUFFLENBQUM7b0JBQzdCLHlCQUF5QjtvQkFDekIsTUFBTTtnQkFDUixDQUFDO2dCQUNELFVBQVUsR0FBRyxTQUFTLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDckIsTUFBTSxJQUFJLEtBQUssQ0FBQywwRUFBMEUsQ0FBQyxDQUFD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Q3JJLENBQUM7UUFDSixDQUFDO1FBRUQsMkNBQTJDO1FBQzNDLElBQUksYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsT0FBTyxFQUFFLEdBQUcsUUFBUSxZQUFZLGFBQWEsb0NBQW9DLFlBQVksQ0FBQyxPQUFPLDJDQUEyQzthQUNqSixDQUFDO1FBQ0osQ0FBQztRQUVELHNDQUFzQztRQUN0QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDcEYsSUFBSSxhQUFhLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDeEIsT0FBTztnQkFDTCxLQUFLLEVBQUUsSUFBSTtnQkFDWCxPQUFPLEVBQUUsR0FBRyxRQUFRLFlBQVksYUFBYSxjQUFjLFlBQVksQ0FBQyxXQUFXLHdDQUF3QzthQUM1SCxDQUFDO1FBQ0osQ0FBQztRQUVELHFCQUFxQjtRQUNyQixPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVmVyc2lvbiBtYW5hZ2VtZW50IGFuZCBjb21wYXJpc29uIHV0aWxpdGllc1xuICovXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmV4cG9ydCBjbGFzcyBWZXJzaW9uTWFuYWdlciB7XG4gIC8qKlxuICAgKiBHZXQgY3VycmVudCB2ZXJzaW9uIGZyb20gcGFja2FnZS5qc29uXG4gICAqL1xuICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIC8vIFVzZSBwcm9jZXNzLmN3ZCgpIGFzIGEgYmFzZSwgdGhlbiBzZWFyY2ggdXB3YXJkIGZvciBwYWNrYWdlLmpzb25cbiAgICBsZXQgY3VycmVudERpciA9IHByb2Nlc3MuY3dkKCk7XG4gICAgbGV0IHBhY2thZ2VKc29uUGF0aDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgXG4gICAgLy8gU2VhcmNoIHVwIHRvIDUgbGV2ZWxzIGZvciBwYWNrYWdlLmpzb25cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDU7IGkrKykge1xuICAgICAgY29uc3QgY2FuZGlkYXRlUGF0aCA9IHBhdGguam9pbihjdXJyZW50RGlyLCAncGFja2FnZS5qc29uJyk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmcy5hY2Nlc3MoY2FuZGlkYXRlUGF0aCk7XG4gICAgICAgIHBhY2thZ2VKc29uUGF0aCA9IGNhbmRpZGF0ZVBhdGg7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIEZpbGUgZG9lc24ndCBleGlzdCwgdHJ5IHBhcmVudCBkaXJlY3RvcnlcbiAgICAgICAgY29uc3QgcGFyZW50RGlyID0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpO1xuICAgICAgICBpZiAocGFyZW50RGlyID09PSBjdXJyZW50RGlyKSB7XG4gICAgICAgICAgLy8gV2UndmUgcmVhY2hlZCB0aGUgcm9vdFxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnREaXIgPSBwYXJlbnREaXI7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIGlmICghcGFja2FnZUpzb25QYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIHBhY2thZ2UuanNvbiBpbiBjdXJyZW50IGRpcmVjdG9yeSBvciBhbnkgcGFyZW50IGRpcmVjdG9yeScpO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBwYWNrYWdlQ29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhY2thZ2VKc29uUGF0aCwgJ3V0Zi04Jyk7XG4gICAgY29uc3QgcGFja2FnZURhdGEgPSBKU09OLnBhcnNlKHBhY2thZ2VDb250ZW50KTtcbiAgICByZXR1cm4gcGFja2FnZURhdGEudmVyc2lvbjtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEVuaGFuY2VkIHNlbWFudGljIHZlcnNpb24gY29tcGFyaXNvbiBzdXBwb3J0aW5nIHByZS1yZWxlYXNlIHZlcnNpb25zXG4gICAqIFJldHVybnM6IC0xIGlmIHYxIDwgdjIsIDAgaWYgdjEgPT0gdjIsIDEgaWYgdjEgPiB2MlxuICAgKi9cbiAgY29tcGFyZVZlcnNpb25zKHZlcnNpb24xOiBzdHJpbmcsIHZlcnNpb24yOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIC8vIE5vcm1hbGl6ZSB2ZXJzaW9ucyBieSByZW1vdmluZyAndicgcHJlZml4XG4gICAgY29uc3QgdjEgPSB2ZXJzaW9uMS5yZXBsYWNlKC9edi8sICcnKTtcbiAgICBjb25zdCB2MiA9IHZlcnNpb24yLnJlcGxhY2UoL152LywgJycpO1xuICAgIFxuICAgIC8vIFNwbGl0IHZlcnNpb24gYW5kIHByZS1yZWxlYXNlIHBhcnRzXG4gICAgY29uc3QgW3YxbWFpbiwgdjFwcmVdID0gdjEuc3BsaXQoJy0nKTtcbiAgICBjb25zdCBbdjJtYWluLCB2MnByZV0gPSB2Mi5zcGxpdCgnLScpO1xuICAgIFxuICAgIC8vIENvbXBhcmUgbWFpbiB2ZXJzaW9uIHBhcnRzICh4LnkueilcbiAgICBjb25zdCB2MXBhcnRzID0gdjFtYWluLnNwbGl0KCcuJykubWFwKHBhcnQgPT4gcGFyc2VJbnQocGFydCkgfHwgMCk7XG4gICAgY29uc3QgdjJwYXJ0cyA9IHYybWFpbi5zcGxpdCgnLicpLm1hcChwYXJ0ID0+IHBhcnNlSW50KHBhcnQpIHx8IDApO1xuICAgIFxuICAgIGNvbnN0IG1heExlbmd0aCA9IE1hdGgubWF4KHYxcGFydHMubGVuZ3RoLCB2MnBhcnRzLmxlbmd0aCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXhMZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgdjFwYXJ0ID0gdjFwYXJ0c1tpXSB8fCAwO1xuICAgICAgY29uc3QgdjJwYXJ0ID0gdjJwYXJ0c1tpXSB8fCAwO1xuICAgICAgXG4gICAgICBpZiAodjFwYXJ0IDwgdjJwYXJ0KSByZXR1cm4gLTE7XG4gICAgICBpZiAodjFwYXJ0ID4gdjJwYXJ0KSByZXR1cm4gMTtcbiAgICB9XG4gICAgXG4gICAgLy8gSWYgbWFpbiB2ZXJzaW9ucyBhcmUgZXF1YWwsIGNvbXBhcmUgcHJlLXJlbGVhc2UgdmVyc2lvbnNcbiAgICAvLyBWZXJzaW9uIHdpdGhvdXQgcHJlLXJlbGVhc2UgaXMgZ3JlYXRlciB0aGFuIHZlcnNpb24gd2l0aCBwcmUtcmVsZWFzZVxuICAgIGlmICghdjFwcmUgJiYgdjJwcmUpIHJldHVybiAxOyAgIC8vIDEuMC4wID4gMS4wLjAtYmV0YVxuICAgIGlmICh2MXByZSAmJiAhdjJwcmUpIHJldHVybiAtMTsgIC8vIDEuMC4wLWJldGEgPCAxLjAuMFxuICAgIGlmICghdjFwcmUgJiYgIXYycHJlKSByZXR1cm4gMDsgIC8vIDEuMC4wID09IDEuMC4wXG4gICAgXG4gICAgLy8gQm90aCBoYXZlIHByZS1yZWxlYXNlLCBjb21wYXJlIGxleGljb2dyYXBoaWNhbGx5XG4gICAgcmV0dXJuIHYxcHJlLmxvY2FsZUNvbXBhcmUodjJwcmUpO1xuICB9XG4gIFxuICAvKipcbiAgICogUGFyc2UgdmVyc2lvbiBmcm9tIGRlcGVuZGVuY3kgb3V0cHV0XG4gICAqL1xuICBwYXJzZVZlcnNpb25Gcm9tT3V0cHV0KG91dHB1dDogc3RyaW5nLCB0b29sOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAvLyBHaXQgdmVyc2lvbiBvdXRwdXQ6IFwiZ2l0IHZlcnNpb24gMi4zOS4yXCJcbiAgICAvLyBucG0gdmVyc2lvbiBvdXRwdXQ6IFwiOC4xOS4yXCIgb3IgSlNPTiB3aXRoIHZlcnNpb24gaW5mb1xuICAgIFxuICAgIGlmICh0b29sID09PSAnZ2l0Jykge1xuICAgICAgY29uc3QgbWF0Y2ggPSBvdXRwdXQubWF0Y2goL2dpdCB2ZXJzaW9uIChcXGQrXFwuXFxkK1xcLlxcZCspLyk7XG4gICAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXSA6IG51bGw7XG4gICAgfSBlbHNlIGlmICh0b29sID09PSAnbnBtJykge1xuICAgICAgLy8gbnBtIG1pZ2h0IHJldHVybiBqdXN0IHRoZSB2ZXJzaW9uIG51bWJlciBvciBKU09OXG4gICAgICBjb25zdCBjbGVhbk91dHB1dCA9IG91dHB1dC50cmltKCk7XG4gICAgICBpZiAoY2xlYW5PdXRwdXQubWF0Y2goL15cXGQrXFwuXFxkK1xcLlxcZCsvKSkge1xuICAgICAgICByZXR1cm4gY2xlYW5PdXRwdXQuc3BsaXQoJ1xcbicpWzBdOyAvLyBGaXJzdCBsaW5lIGlmIG11bHRpcGxlIGxpbmVzXG4gICAgICB9XG4gICAgICAvLyBUcnkgdG8gcGFyc2UgYXMgSlNPTiBpZiBpdCBsb29rcyBsaWtlIEpTT05cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoY2xlYW5PdXRwdXQpO1xuICAgICAgICByZXR1cm4gcGFyc2VkLm5wbSB8fCBwYXJzZWQudmVyc2lvbiB8fCBudWxsO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIElmIG5vdCBKU09OLCB0cnkgdG8gZXh0cmFjdCB2ZXJzaW9uIHBhdHRlcm5cbiAgICAgICAgY29uc3QgbWF0Y2ggPSBjbGVhbk91dHB1dC5tYXRjaCgvKFxcZCtcXC5cXGQrXFwuXFxkKykvKTtcbiAgICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBcbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgYSBkZXBlbmRlbmN5IHZlcnNpb24gbWVldHMgcmVxdWlyZW1lbnRzXG4gICAqL1xuICB2YWxpZGF0ZURlcGVuZGVuY3lWZXJzaW9uKFxuICAgIGFjdHVhbFZlcnNpb246IHN0cmluZywgXG4gICAgcmVxdWlyZW1lbnRzOiB7IG1pbmltdW06IHN0cmluZzsgbWF4aW11bTogc3RyaW5nOyByZWNvbW1lbmRlZDogc3RyaW5nIH0sXG4gICAgdG9vbE5hbWU6IHN0cmluZ1xuICApOiB7IHZhbGlkOiBib29sZWFuOyB3YXJuaW5nPzogc3RyaW5nOyBlcnJvcj86IHN0cmluZyB9IHtcbiAgICBjb25zdCBtaW5Db21wYXJpc29uID0gdGhpcy5jb21wYXJlVmVyc2lvbnMoYWN0dWFsVmVyc2lvbiwgcmVxdWlyZW1lbnRzLm1pbmltdW0pO1xuICAgIGNvbnN0IG1heENvbXBhcmlzb24gPSB0aGlzLmNvbXBhcmVWZXJzaW9ucyhhY3R1YWxWZXJzaW9uLCByZXF1aXJlbWVudHMubWF4aW11bSk7XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgdmVyc2lvbiBpcyBiZWxvdyBtaW5pbXVtXG4gICAgaWYgKG1pbkNvbXBhcmlzb24gPCAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgJHt0b29sTmFtZX0gdmVyc2lvbiAke2FjdHVhbFZlcnNpb259IGlzIGJlbG93IG1pbmltdW0gcmVxdWlyZWQgdmVyc2lvbiAke3JlcXVpcmVtZW50cy5taW5pbXVtfS4gUGxlYXNlIHVwZ3JhZGUgJHt0b29sTmFtZX0uYFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgdmVyc2lvbiBpcyBhYm92ZSBtYXhpbXVtIHRlc3RlZFxuICAgIGlmIChtYXhDb21wYXJpc29uID4gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIHdhcm5pbmc6IGAke3Rvb2xOYW1lfSB2ZXJzaW9uICR7YWN0dWFsVmVyc2lvbn0gaXMgYWJvdmUgbWF4aW11bSB0ZXN0ZWQgdmVyc2lvbiAke3JlcXVpcmVtZW50cy5tYXhpbXVtfS4gU29tZSBmZWF0dXJlcyBtYXkgbm90IHdvcmsgYXMgZXhwZWN0ZWQuYFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgbm90IGF0IHJlY29tbWVuZGVkIHZlcnNpb25cbiAgICBjb25zdCByZWNDb21wYXJpc29uID0gdGhpcy5jb21wYXJlVmVyc2lvbnMoYWN0dWFsVmVyc2lvbiwgcmVxdWlyZW1lbnRzLnJlY29tbWVuZGVkKTtcbiAgICBpZiAocmVjQ29tcGFyaXNvbiAhPT0gMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IHRydWUsXG4gICAgICAgIHdhcm5pbmc6IGAke3Rvb2xOYW1lfSB2ZXJzaW9uICR7YWN0dWFsVmVyc2lvbn0gd29ya3MgYnV0ICR7cmVxdWlyZW1lbnRzLnJlY29tbWVuZGVkfSBpcyByZWNvbW1lbmRlZCBmb3Igb3B0aW1hbCBzdGFiaWxpdHkuYFxuICAgICAgfTtcbiAgICB9XG4gICAgXG4gICAgLy8gVmVyc2lvbiBpcyBwZXJmZWN0XG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTtcbiAgfVxufSJdfQ==
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVmVyc2lvbk1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXBkYXRlL1ZlcnNpb25NYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNwQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFaEUsTUFBTSxPQUFPLGNBQWM7SUFDekI7O09BRUc7SUFDSCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLGtEQUFrRDtRQUNsRCxJQUFJLENBQUM7WUFDSCxNQUFNLEVBQUUsZUFBZSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUNwRSxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLENBQUMsS0FBSyxDQUFDLDRDQUE0QyxlQUFlLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RSxPQUFPLGVBQWUsQ0FBQztZQUN6QixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLDBFQUEwRSxDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUVELDhCQUE4QjtRQUM5QixNQUFNLGdCQUFnQixHQUFHLG9CQUFvQixDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFFcEUsOERBQThEO1FBQzlELElBQUksZ0JBQWdCLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDL0IsTUFBTSxPQUFPLEdBQUcsb0JBQW9CLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUN4RCxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNaLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO2dCQUMzRCxJQUFJLENBQUM7b0JBQ0gsTUFBTSxjQUFjLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUMsQ0FBQztvQkFDbkUsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztvQkFDL0MsT0FBTyxXQUFXLENBQUMsT0FBTyxDQUFDO2dCQUM3QixDQUFDO2dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7b0JBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyw0REFBNEQsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDcEYsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsMkRBQTJEO1FBQzNELElBQUksZ0JBQWdCLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDL0IsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7WUFDdkMsTUFBTSxlQUFlLEdBQUcsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3RELElBQUksVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUM7WUFFL0MsaUNBQWlDO1lBQ2pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDM0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7Z0JBQzVELElBQUksQ0FBQztvQkFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQy9CLE1BQU0sY0FBYyxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7b0JBQ2pFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7b0JBQy9DLE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQztnQkFDN0IsQ0FBQztnQkFBQyxNQUFNLENBQUM7b0JBQ1AsMkNBQTJDO29CQUMzQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUMzQyxJQUFJLFNBQVMsS0FBSyxVQUFVLEVBQUUsQ0FBQzt3QkFDN0IsTUFBTTtvQkFDUixDQUFDO29CQUNELFVBQVUsR0FBRyxTQUFTLENBQUM7Z0JBQ3pCLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELHFEQUFxRDtRQUNyRCxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDL0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQzNCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQztnQkFDSCxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBQy9CLE1BQU0sY0FBYyxHQUFHLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2pFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQy9DLE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQztZQUM3QixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzNDLElBQUksU0FBUyxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUM3QixNQUFNO2dCQUNSLENBQUM7Z0JBQ0QsVUFBVSxHQUFHLFNBQVMsQ0FBQztZQUN6QixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sSUFBSSxLQUFLLENBQUMsMkVBQTJFLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsZUFBZSxDQUFDLFFBQWdCLEVBQUUsUUFBZ0I7UUFDaEQsNENBQTRDO1FBQzVDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXRDLHNDQUFzQztRQUN0QyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXRDLHFDQUFxQztRQUNyQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNuRSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUVuRSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNuQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFL0IsSUFBSSxNQUFNLEdBQUcsTUFBTTtnQkFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksTUFBTSxHQUFHLE1BQU07Z0JBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUVELDJEQUEyRDtRQUMzRCx1RUFBdUU7UUFDdkUsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLO1lBQUUsT0FBTyxDQUFDLENBQUMsQ0FBRyxxQkFBcUI7UUFDdEQsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFFLHFCQUFxQjtRQUN0RCxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUUsaUJBQWlCO1FBRWxELG1EQUFtRDtRQUNuRCxPQUFPLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsc0JBQXNCLENBQUMsTUFBYyxFQUFFLElBQVk7UUFDakQsMkNBQTJDO1FBQzNDLHlEQUF5RDtRQUV6RCxJQUFJLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUNuQixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLDZCQUE2QixDQUFDLENBQUM7WUFDMUQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2pDLENBQUM7YUFBTSxJQUFJLElBQUksS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUMxQixtREFBbUQ7WUFDbkQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2xDLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hDLE9BQU8sV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLCtCQUErQjtZQUNwRSxDQUFDO1lBQ0QsNkNBQTZDO1lBQzdDLElBQUksQ0FBQztnQkFDSCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUN2QyxPQUFPLE1BQU0sQ0FBQyxHQUFHLElBQUksTUFBTSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUM7WUFDOUMsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCw4Q0FBOEM7Z0JBQzlDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDbkQsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ2pDLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSCx5QkFBeUIsQ0FDdkIsYUFBcUIsRUFDckIsWUFBdUUsRUFDdkUsUUFBZ0I7UUFFaEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hGLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVoRixvQ0FBb0M7UUFDcEMsSUFBSSxhQUFhLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTztnQkFDTCxLQUFLLEVBQUUsS0FBSztnQkFDWixLQUFLLEVBQUUsR0FBRyxRQUFRLFlBQVksYUFBYSxzQ0FBc0MsWUFBWSxDQUFDLE9BQU8sb0JBQW9CLFFBQVEsR0FBRzthQUNySSxDQUFDO1FBQ0osQ0FBQztRQUVELDJDQUEyQztRQUMzQyxJQUFJLGFBQWEsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QixPQUFPO2dCQUNMLEtBQUssRUFBRSxJQUFJO2dCQUNYLE9BQU8sRUFBRSxHQUFHLFFBQVEsWUFBWSxhQUFhLG9DQUFvQyxZQUFZLENBQUMsT0FBTywyQ0FBMkM7YUFDakosQ0FBQztRQUNKLENBQUM7UUFFRCxzQ0FBc0M7UUFDdEMsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BGLElBQUksYUFBYSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU87Z0JBQ0wsS0FBSyxFQUFFLElBQUk7Z0JBQ1gsT0FBTyxFQUFFLEdBQUcsUUFBUSxZQUFZLGFBQWEsY0FBYyxZQUFZLENBQUMsV0FBVyx3Q0FBd0M7YUFDNUgsQ0FBQztRQUNKLENBQUM7UUFFRCxxQkFBcUI7UUFDckIsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUN6QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFZlcnNpb24gbWFuYWdlbWVudCBhbmQgY29tcGFyaXNvbiB1dGlsaXRpZXNcbiAqL1xuXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy9wcm9taXNlcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gJ3VybCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgSW5zdGFsbGF0aW9uRGV0ZWN0b3IgfSBmcm9tICcuLi91dGlscy9pbnN0YWxsYXRpb24uanMnO1xuXG5leHBvcnQgY2xhc3MgVmVyc2lvbk1hbmFnZXIge1xuICAvKipcbiAgICogR2V0IGN1cnJlbnQgdmVyc2lvbiBmcm9tIHBhY2thZ2UuanNvbiBvciBlbWJlZGRlZCB2ZXJzaW9uXG4gICAqL1xuICBhc3luYyBnZXRDdXJyZW50VmVyc2lvbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIC8vIEZpcnN0LCB0cnkgdG8gaW1wb3J0IHRoZSBnZW5lcmF0ZWQgdmVyc2lvbiBmaWxlXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgUEFDS0FHRV9WRVJTSU9OIH0gPSBhd2FpdCBpbXBvcnQoJy4uL2dlbmVyYXRlZC92ZXJzaW9uLmpzJyk7XG4gICAgICBpZiAoUEFDS0FHRV9WRVJTSU9OKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgW1ZlcnNpb25NYW5hZ2VyXSBVc2luZyBlbWJlZGRlZCB2ZXJzaW9uOiAke1BBQ0tBR0VfVkVSU0lPTn1gKTtcbiAgICAgICAgcmV0dXJuIFBBQ0tBR0VfVkVSU0lPTjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdbVmVyc2lvbk1hbmFnZXJdIE5vIGVtYmVkZGVkIHZlcnNpb24gZm91bmQsIHdpbGwgc2VhcmNoIGZvciBwYWNrYWdlLmpzb24nKTtcbiAgICB9XG4gICAgXG4gICAgLy8gRGV0ZXJtaW5lIGluc3RhbGxhdGlvbiB0eXBlXG4gICAgY29uc3QgaW5zdGFsbGF0aW9uVHlwZSA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldEluc3RhbGxhdGlvblR5cGUoKTtcbiAgICBcbiAgICAvLyBGb3IgbnBtIGluc3RhbGxhdGlvbnMsIGxvb2sgcmVsYXRpdmUgdG8gdGhlIG1vZHVsZSBsb2NhdGlvblxuICAgIGlmIChpbnN0YWxsYXRpb25UeXBlID09PSAnbnBtJykge1xuICAgICAgY29uc3QgbnBtUGF0aCA9IEluc3RhbGxhdGlvbkRldGVjdG9yLmdldE5wbUdsb2JhbFBhdGgoKTtcbiAgICAgIGlmIChucG1QYXRoKSB7XG4gICAgICAgIGNvbnN0IHBhY2thZ2VKc29uUGF0aCA9IHBhdGguam9pbihucG1QYXRoLCAncGFja2FnZS5qc29uJyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcGFja2FnZUNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShwYWNrYWdlSnNvblBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgIGNvbnN0IHBhY2thZ2VEYXRhID0gSlNPTi5wYXJzZShwYWNrYWdlQ29udGVudCk7XG4gICAgICAgICAgcmV0dXJuIHBhY2thZ2VEYXRhLnZlcnNpb247XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdbVmVyc2lvbk1hbmFnZXJdIEVycm9yIHJlYWRpbmcgcGFja2FnZS5qc29uIGZyb20gbnBtIHBhdGg6JywgZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIEZvciBnaXQgaW5zdGFsbGF0aW9ucywgc2VhcmNoIGZyb20gY3VycmVudCBmaWxlIGxvY2F0aW9uXG4gICAgaWYgKGluc3RhbGxhdGlvblR5cGUgPT09ICdnaXQnKSB7XG4gICAgICBjb25zdCBjdXJyZW50RmlsZVVybCA9IGltcG9ydC5tZXRhLnVybDtcbiAgICAgIGNvbnN0IGN1cnJlbnRGaWxlUGF0aCA9IGZpbGVVUkxUb1BhdGgoY3VycmVudEZpbGVVcmwpO1xuICAgICAgbGV0IGN1cnJlbnREaXIgPSBwYXRoLmRpcm5hbWUoY3VycmVudEZpbGVQYXRoKTtcbiAgICAgIFxuICAgICAgLy8gU2VhcmNoIHVwd2FyZCBmb3IgcGFja2FnZS5qc29uXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDU7IGkrKykge1xuICAgICAgICBjb25zdCBjYW5kaWRhdGVQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBmcy5hY2Nlc3MoY2FuZGlkYXRlUGF0aCk7XG4gICAgICAgICAgY29uc3QgcGFja2FnZUNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShjYW5kaWRhdGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgICBjb25zdCBwYWNrYWdlRGF0YSA9IEpTT04ucGFyc2UocGFja2FnZUNvbnRlbnQpO1xuICAgICAgICAgIHJldHVybiBwYWNrYWdlRGF0YS52ZXJzaW9uO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBGaWxlIGRvZXNuJ3QgZXhpc3QsIHRyeSBwYXJlbnQgZGlyZWN0b3J5XG4gICAgICAgICAgY29uc3QgcGFyZW50RGlyID0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpO1xuICAgICAgICAgIGlmIChwYXJlbnREaXIgPT09IGN1cnJlbnREaXIpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50RGlyID0gcGFyZW50RGlyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIExhc3QgcmVzb3J0OiB0cnkgcHJvY2Vzcy5jd2QoKSAob3JpZ2luYWwgYmVoYXZpb3IpXG4gICAgbGV0IGN1cnJlbnREaXIgPSBwcm9jZXNzLmN3ZCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTsgaSsrKSB7XG4gICAgICBjb25zdCBjYW5kaWRhdGVQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsICdwYWNrYWdlLmpzb24nKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmFjY2VzcyhjYW5kaWRhdGVQYXRoKTtcbiAgICAgICAgY29uc3QgcGFja2FnZUNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShjYW5kaWRhdGVQYXRoLCAndXRmLTgnKTtcbiAgICAgICAgY29uc3QgcGFja2FnZURhdGEgPSBKU09OLnBhcnNlKHBhY2thZ2VDb250ZW50KTtcbiAgICAgICAgcmV0dXJuIHBhY2thZ2VEYXRhLnZlcnNpb247XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgY29uc3QgcGFyZW50RGlyID0gcGF0aC5kaXJuYW1lKGN1cnJlbnREaXIpO1xuICAgICAgICBpZiAocGFyZW50RGlyID09PSBjdXJyZW50RGlyKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudERpciA9IHBhcmVudERpcjtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZGV0ZXJtaW5lIHZlcnNpb24uIFBsZWFzZSBlbnN1cmUgeW91IGhhdmUgYSB2YWxpZCBpbnN0YWxsYXRpb24uJyk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBFbmhhbmNlZCBzZW1hbnRpYyB2ZXJzaW9uIGNvbXBhcmlzb24gc3VwcG9ydGluZyBwcmUtcmVsZWFzZSB2ZXJzaW9uc1xuICAgKiBSZXR1cm5zOiAtMSBpZiB2MSA8IHYyLCAwIGlmIHYxID09IHYyLCAxIGlmIHYxID4gdjJcbiAgICovXG4gIGNvbXBhcmVWZXJzaW9ucyh2ZXJzaW9uMTogc3RyaW5nLCB2ZXJzaW9uMjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAvLyBOb3JtYWxpemUgdmVyc2lvbnMgYnkgcmVtb3ZpbmcgJ3YnIHByZWZpeFxuICAgIGNvbnN0IHYxID0gdmVyc2lvbjEucmVwbGFjZSgvXnYvLCAnJyk7XG4gICAgY29uc3QgdjIgPSB2ZXJzaW9uMi5yZXBsYWNlKC9edi8sICcnKTtcbiAgICBcbiAgICAvLyBTcGxpdCB2ZXJzaW9uIGFuZCBwcmUtcmVsZWFzZSBwYXJ0c1xuICAgIGNvbnN0IFt2MW1haW4sIHYxcHJlXSA9IHYxLnNwbGl0KCctJyk7XG4gICAgY29uc3QgW3YybWFpbiwgdjJwcmVdID0gdjIuc3BsaXQoJy0nKTtcbiAgICBcbiAgICAvLyBDb21wYXJlIG1haW4gdmVyc2lvbiBwYXJ0cyAoeC55LnopXG4gICAgY29uc3QgdjFwYXJ0cyA9IHYxbWFpbi5zcGxpdCgnLicpLm1hcChwYXJ0ID0+IHBhcnNlSW50KHBhcnQpIHx8IDApO1xuICAgIGNvbnN0IHYycGFydHMgPSB2Mm1haW4uc3BsaXQoJy4nKS5tYXAocGFydCA9PiBwYXJzZUludChwYXJ0KSB8fCAwKTtcbiAgICBcbiAgICBjb25zdCBtYXhMZW5ndGggPSBNYXRoLm1heCh2MXBhcnRzLmxlbmd0aCwgdjJwYXJ0cy5sZW5ndGgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF4TGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHYxcGFydCA9IHYxcGFydHNbaV0gfHwgMDtcbiAgICAgIGNvbnN0IHYycGFydCA9IHYycGFydHNbaV0gfHwgMDtcbiAgICAgIFxuICAgICAgaWYgKHYxcGFydCA8IHYycGFydCkgcmV0dXJuIC0xO1xuICAgICAgaWYgKHYxcGFydCA+IHYycGFydCkgcmV0dXJuIDE7XG4gICAgfVxuICAgIFxuICAgIC8vIElmIG1haW4gdmVyc2lvbnMgYXJlIGVxdWFsLCBjb21wYXJlIHByZS1yZWxlYXNlIHZlcnNpb25zXG4gICAgLy8gVmVyc2lvbiB3aXRob3V0IHByZS1yZWxlYXNlIGlzIGdyZWF0ZXIgdGhhbiB2ZXJzaW9uIHdpdGggcHJlLXJlbGVhc2VcbiAgICBpZiAoIXYxcHJlICYmIHYycHJlKSByZXR1cm4gMTsgICAvLyAxLjAuMCA+IDEuMC4wLWJldGFcbiAgICBpZiAodjFwcmUgJiYgIXYycHJlKSByZXR1cm4gLTE7ICAvLyAxLjAuMC1iZXRhIDwgMS4wLjBcbiAgICBpZiAoIXYxcHJlICYmICF2MnByZSkgcmV0dXJuIDA7ICAvLyAxLjAuMCA9PSAxLjAuMFxuICAgIFxuICAgIC8vIEJvdGggaGF2ZSBwcmUtcmVsZWFzZSwgY29tcGFyZSBsZXhpY29ncmFwaGljYWxseVxuICAgIHJldHVybiB2MXByZS5sb2NhbGVDb21wYXJlKHYycHJlKTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIFBhcnNlIHZlcnNpb24gZnJvbSBkZXBlbmRlbmN5IG91dHB1dFxuICAgKi9cbiAgcGFyc2VWZXJzaW9uRnJvbU91dHB1dChvdXRwdXQ6IHN0cmluZywgdG9vbDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgLy8gR2l0IHZlcnNpb24gb3V0cHV0OiBcImdpdCB2ZXJzaW9uIDIuMzkuMlwiXG4gICAgLy8gbnBtIHZlcnNpb24gb3V0cHV0OiBcIjguMTkuMlwiIG9yIEpTT04gd2l0aCB2ZXJzaW9uIGluZm9cbiAgICBcbiAgICBpZiAodG9vbCA9PT0gJ2dpdCcpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gb3V0cHV0Lm1hdGNoKC9naXQgdmVyc2lvbiAoXFxkK1xcLlxcZCtcXC5cXGQrKS8pO1xuICAgICAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0gOiBudWxsO1xuICAgIH0gZWxzZSBpZiAodG9vbCA9PT0gJ25wbScpIHtcbiAgICAgIC8vIG5wbSBtaWdodCByZXR1cm4ganVzdCB0aGUgdmVyc2lvbiBudW1iZXIgb3IgSlNPTlxuICAgICAgY29uc3QgY2xlYW5PdXRwdXQgPSBvdXRwdXQudHJpbSgpO1xuICAgICAgaWYgKGNsZWFuT3V0cHV0Lm1hdGNoKC9eXFxkK1xcLlxcZCtcXC5cXGQrLykpIHtcbiAgICAgICAgcmV0dXJuIGNsZWFuT3V0cHV0LnNwbGl0KCdcXG4nKVswXTsgLy8gRmlyc3QgbGluZSBpZiBtdWx0aXBsZSBsaW5lc1xuICAgICAgfVxuICAgICAgLy8gVHJ5IHRvIHBhcnNlIGFzIEpTT04gaWYgaXQgbG9va3MgbGlrZSBKU09OXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGNsZWFuT3V0cHV0KTtcbiAgICAgICAgcmV0dXJuIHBhcnNlZC5ucG0gfHwgcGFyc2VkLnZlcnNpb24gfHwgbnVsbDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBJZiBub3QgSlNPTiwgdHJ5IHRvIGV4dHJhY3QgdmVyc2lvbiBwYXR0ZXJuXG4gICAgICAgIGNvbnN0IG1hdGNoID0gY2xlYW5PdXRwdXQubWF0Y2goLyhcXGQrXFwuXFxkK1xcLlxcZCspLyk7XG4gICAgICAgIHJldHVybiBtYXRjaCA/IG1hdGNoWzFdIDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aGF0IGEgZGVwZW5kZW5jeSB2ZXJzaW9uIG1lZXRzIHJlcXVpcmVtZW50c1xuICAgKi9cbiAgdmFsaWRhdGVEZXBlbmRlbmN5VmVyc2lvbihcbiAgICBhY3R1YWxWZXJzaW9uOiBzdHJpbmcsIFxuICAgIHJlcXVpcmVtZW50czogeyBtaW5pbXVtOiBzdHJpbmc7IG1heGltdW06IHN0cmluZzsgcmVjb21tZW5kZWQ6IHN0cmluZyB9LFxuICAgIHRvb2xOYW1lOiBzdHJpbmdcbiAgKTogeyB2YWxpZDogYm9vbGVhbjsgd2FybmluZz86IHN0cmluZzsgZXJyb3I/OiBzdHJpbmcgfSB7XG4gICAgY29uc3QgbWluQ29tcGFyaXNvbiA9IHRoaXMuY29tcGFyZVZlcnNpb25zKGFjdHVhbFZlcnNpb24sIHJlcXVpcmVtZW50cy5taW5pbXVtKTtcbiAgICBjb25zdCBtYXhDb21wYXJpc29uID0gdGhpcy5jb21wYXJlVmVyc2lvbnMoYWN0dWFsVmVyc2lvbiwgcmVxdWlyZW1lbnRzLm1heGltdW0pO1xuICAgIFxuICAgIC8vIENoZWNrIGlmIHZlcnNpb24gaXMgYmVsb3cgbWluaW11bVxuICAgIGlmIChtaW5Db21wYXJpc29uIDwgMCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcjogYCR7dG9vbE5hbWV9IHZlcnNpb24gJHthY3R1YWxWZXJzaW9ufSBpcyBiZWxvdyBtaW5pbXVtIHJlcXVpcmVkIHZlcnNpb24gJHtyZXF1aXJlbWVudHMubWluaW11bX0uIFBsZWFzZSB1cGdyYWRlICR7dG9vbE5hbWV9LmBcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIENoZWNrIGlmIHZlcnNpb24gaXMgYWJvdmUgbWF4aW11bSB0ZXN0ZWRcbiAgICBpZiAobWF4Q29tcGFyaXNvbiA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB3YXJuaW5nOiBgJHt0b29sTmFtZX0gdmVyc2lvbiAke2FjdHVhbFZlcnNpb259IGlzIGFib3ZlIG1heGltdW0gdGVzdGVkIHZlcnNpb24gJHtyZXF1aXJlbWVudHMubWF4aW11bX0uIFNvbWUgZmVhdHVyZXMgbWF5IG5vdCB3b3JrIGFzIGV4cGVjdGVkLmBcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIENoZWNrIGlmIG5vdCBhdCByZWNvbW1lbmRlZCB2ZXJzaW9uXG4gICAgY29uc3QgcmVjQ29tcGFyaXNvbiA9IHRoaXMuY29tcGFyZVZlcnNpb25zKGFjdHVhbFZlcnNpb24sIHJlcXVpcmVtZW50cy5yZWNvbW1lbmRlZCk7XG4gICAgaWYgKHJlY0NvbXBhcmlzb24gIT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICB3YXJuaW5nOiBgJHt0b29sTmFtZX0gdmVyc2lvbiAke2FjdHVhbFZlcnNpb259IHdvcmtzIGJ1dCAke3JlcXVpcmVtZW50cy5yZWNvbW1lbmRlZH0gaXMgcmVjb21tZW5kZWQgZm9yIG9wdGltYWwgc3RhYmlsaXR5LmBcbiAgICAgIH07XG4gICAgfVxuICAgIFxuICAgIC8vIFZlcnNpb24gaXMgcGVyZmVjdFxuICAgIHJldHVybiB7IHZhbGlkOiB0cnVlIH07XG4gIH1cbn0iXX0=
@@ -0,0 +1,83 @@
1
+ export interface CopyOptions {
2
+ onProgress?: (copied: number, total: number, currentFile: string) => void;
3
+ excludePatterns?: string[];
4
+ maxRetries?: number;
5
+ }
6
+ export interface FileStats {
7
+ totalFiles: number;
8
+ totalSize: number;
9
+ }
10
+ /**
11
+ * Cross-platform file operations utility
12
+ * Centralizes common file operations with progress reporting and error handling
13
+ */
14
+ export declare class FileOperations {
15
+ /**
16
+ * Recursively copy a directory with progress reporting
17
+ * Works cross-platform without relying on shell commands
18
+ */
19
+ static copyDirectory(src: string, dest: string, options?: CopyOptions): Promise<void>;
20
+ /**
21
+ * Calculate directory statistics for progress reporting
22
+ */
23
+ private static calculateDirectoryStats;
24
+ /**
25
+ * Internal recursive copy implementation
26
+ */
27
+ private static copyDirectoryRecursive;
28
+ /**
29
+ * Copy a single file with retry logic
30
+ */
31
+ private static copyFileWithRetry;
32
+ /**
33
+ * Check if a file/directory should be excluded
34
+ */
35
+ private static shouldExclude;
36
+ /**
37
+ * Remove a directory with progress reporting
38
+ */
39
+ static removeDirectory(dir: string, options?: {
40
+ onProgress?: (removed: number, total: number) => void;
41
+ }): Promise<void>;
42
+ /**
43
+ * Internal recursive remove implementation
44
+ */
45
+ private static removeDirectoryRecursive;
46
+ /**
47
+ * Create a transaction manager for atomic file operations
48
+ */
49
+ static createTransaction(): FileTransaction;
50
+ }
51
+ /**
52
+ * Transaction manager for atomic file operations
53
+ * Ensures all operations succeed or all are rolled back
54
+ */
55
+ export declare class FileTransaction {
56
+ private operations;
57
+ private completed;
58
+ /**
59
+ * Add a move operation to the transaction
60
+ */
61
+ addMove(source: string, destination: string): Promise<void>;
62
+ /**
63
+ * Add a copy operation to the transaction
64
+ */
65
+ addCopy(source: string, destination: string): Promise<void>;
66
+ /**
67
+ * Add a delete operation to the transaction
68
+ */
69
+ addDelete(path: string, backupPath?: string): Promise<void>;
70
+ /**
71
+ * Commit the transaction (mark as successful)
72
+ */
73
+ commit(): void;
74
+ /**
75
+ * Rollback all operations in reverse order
76
+ */
77
+ rollback(): Promise<void>;
78
+ /**
79
+ * Check if any operations have been performed
80
+ */
81
+ hasOperations(): boolean;
82
+ }
83
+ //# sourceMappingURL=fileOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileOperations.d.ts","sourceRoot":"","sources":["../../src/utils/fileOperations.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB;;;OAGG;WACU,aAAa,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,IAAI,CAAC;IAqBhB;;OAEG;mBACkB,uBAAuB;IAuC5C;;OAEG;mBACkB,sBAAsB;IAqC3C;;OAEG;mBACkB,iBAAiB;IA0BtC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAa5B;;OAEG;WACU,eAAe,CAC1B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;KAAO,GACtE,OAAO,CAAC,IAAI,CAAC;IAYhB;;OAEG;mBACkB,wBAAwB;IA0B7C;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,eAAe;CAG5C;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAKV;IAER,OAAO,CAAC,SAAS,CAAS;IAE1B;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjE;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjE;;OAEG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCjE;;OAEG;IACH,MAAM,IAAI,IAAI;IAId;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB/B;;OAEG;IACH,aAAa,IAAI,OAAO;CAGzB"}
@@ -0,0 +1,291 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ import { logger } from './logger.js';
4
+ /**
5
+ * Cross-platform file operations utility
6
+ * Centralizes common file operations with progress reporting and error handling
7
+ */
8
+ export class FileOperations {
9
+ /**
10
+ * Recursively copy a directory with progress reporting
11
+ * Works cross-platform without relying on shell commands
12
+ */
13
+ static async copyDirectory(src, dest, options = {}) {
14
+ const { onProgress, excludePatterns = [], maxRetries = 3 } = options;
15
+ // First, calculate total files for progress reporting
16
+ const stats = await this.calculateDirectoryStats(src, excludePatterns);
17
+ let copiedFiles = 0;
18
+ await this.copyDirectoryRecursive(src, dest, excludePatterns, maxRetries, (currentFile) => {
19
+ copiedFiles++;
20
+ if (onProgress) {
21
+ onProgress(copiedFiles, stats.totalFiles, currentFile);
22
+ }
23
+ });
24
+ }
25
+ /**
26
+ * Calculate directory statistics for progress reporting
27
+ */
28
+ static async calculateDirectoryStats(dir, excludePatterns) {
29
+ let totalFiles = 0;
30
+ let totalSize = 0;
31
+ try {
32
+ const entries = await fs.readdir(dir, { withFileTypes: true });
33
+ for (const entry of entries) {
34
+ const fullPath = path.join(dir, entry.name);
35
+ // Skip excluded patterns
36
+ if (this.shouldExclude(entry.name, excludePatterns)) {
37
+ continue;
38
+ }
39
+ if (entry.isDirectory()) {
40
+ const subStats = await this.calculateDirectoryStats(fullPath, excludePatterns);
41
+ totalFiles += subStats.totalFiles;
42
+ totalSize += subStats.totalSize;
43
+ }
44
+ else {
45
+ totalFiles++;
46
+ try {
47
+ const stat = await fs.stat(fullPath);
48
+ totalSize += stat.size;
49
+ }
50
+ catch {
51
+ // Ignore stat errors
52
+ }
53
+ }
54
+ }
55
+ }
56
+ catch (error) {
57
+ logger.warn(`[FileOperations] Error calculating stats for ${dir}:`, error);
58
+ }
59
+ return { totalFiles, totalSize };
60
+ }
61
+ /**
62
+ * Internal recursive copy implementation
63
+ */
64
+ static async copyDirectoryRecursive(src, dest, excludePatterns, maxRetries, onFileCopied) {
65
+ // Ensure destination directory exists
66
+ await fs.mkdir(dest, { recursive: true });
67
+ const entries = await fs.readdir(src, { withFileTypes: true });
68
+ for (const entry of entries) {
69
+ const srcPath = path.join(src, entry.name);
70
+ const destPath = path.join(dest, entry.name);
71
+ // Skip excluded patterns
72
+ if (this.shouldExclude(entry.name, excludePatterns)) {
73
+ logger.debug(`[FileOperations] Skipping excluded: ${entry.name}`);
74
+ continue;
75
+ }
76
+ if (entry.isDirectory()) {
77
+ await this.copyDirectoryRecursive(srcPath, destPath, excludePatterns, maxRetries, onFileCopied);
78
+ }
79
+ else {
80
+ await this.copyFileWithRetry(srcPath, destPath, maxRetries);
81
+ onFileCopied(srcPath);
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Copy a single file with retry logic
87
+ */
88
+ static async copyFileWithRetry(src, dest, maxRetries) {
89
+ let lastError = null;
90
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
91
+ try {
92
+ await fs.copyFile(src, dest);
93
+ return; // Success
94
+ }
95
+ catch (error) {
96
+ lastError = error;
97
+ logger.debug(`[FileOperations] Copy attempt ${attempt} failed for ${src}: ${error}`);
98
+ if (attempt < maxRetries) {
99
+ // Wait before retry (exponential backoff)
100
+ await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 100));
101
+ }
102
+ }
103
+ }
104
+ // All retries failed
105
+ throw new Error(`Failed to copy ${src} after ${maxRetries} attempts: ${lastError?.message}`);
106
+ }
107
+ /**
108
+ * Check if a file/directory should be excluded
109
+ */
110
+ static shouldExclude(name, patterns) {
111
+ for (const pattern of patterns) {
112
+ if (pattern.includes('*')) {
113
+ // Simple glob support
114
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
115
+ if (regex.test(name))
116
+ return true;
117
+ }
118
+ else if (name === pattern) {
119
+ return true;
120
+ }
121
+ }
122
+ return false;
123
+ }
124
+ /**
125
+ * Remove a directory with progress reporting
126
+ */
127
+ static async removeDirectory(dir, options = {}) {
128
+ const stats = await this.calculateDirectoryStats(dir, []);
129
+ let removedFiles = 0;
130
+ await this.removeDirectoryRecursive(dir, () => {
131
+ removedFiles++;
132
+ if (options.onProgress) {
133
+ options.onProgress(removedFiles, stats.totalFiles);
134
+ }
135
+ });
136
+ }
137
+ /**
138
+ * Internal recursive remove implementation
139
+ */
140
+ static async removeDirectoryRecursive(dir, onFileRemoved) {
141
+ try {
142
+ const entries = await fs.readdir(dir, { withFileTypes: true });
143
+ for (const entry of entries) {
144
+ const fullPath = path.join(dir, entry.name);
145
+ if (entry.isDirectory()) {
146
+ await this.removeDirectoryRecursive(fullPath, onFileRemoved);
147
+ }
148
+ else {
149
+ await fs.unlink(fullPath);
150
+ onFileRemoved();
151
+ }
152
+ }
153
+ // Remove the now-empty directory
154
+ await fs.rmdir(dir);
155
+ }
156
+ catch (error) {
157
+ logger.error(`[FileOperations] Error removing directory ${dir}:`, error);
158
+ throw error;
159
+ }
160
+ }
161
+ /**
162
+ * Create a transaction manager for atomic file operations
163
+ */
164
+ static createTransaction() {
165
+ return new FileTransaction();
166
+ }
167
+ }
168
+ /**
169
+ * Transaction manager for atomic file operations
170
+ * Ensures all operations succeed or all are rolled back
171
+ */
172
+ export class FileTransaction {
173
+ operations = [];
174
+ completed = false;
175
+ /**
176
+ * Add a move operation to the transaction
177
+ */
178
+ async addMove(source, destination) {
179
+ if (this.completed) {
180
+ throw new Error('Transaction already completed');
181
+ }
182
+ // Perform the move
183
+ await fs.rename(source, destination);
184
+ // Add rollback operation
185
+ this.operations.push({
186
+ type: 'move',
187
+ source,
188
+ destination,
189
+ rollback: async () => {
190
+ try {
191
+ await fs.rename(destination, source);
192
+ }
193
+ catch (error) {
194
+ logger.error(`[FileTransaction] Failed to rollback move from ${destination} to ${source}:`, error);
195
+ }
196
+ }
197
+ });
198
+ }
199
+ /**
200
+ * Add a copy operation to the transaction
201
+ */
202
+ async addCopy(source, destination) {
203
+ if (this.completed) {
204
+ throw new Error('Transaction already completed');
205
+ }
206
+ // Perform the copy
207
+ await FileOperations.copyDirectory(source, destination);
208
+ // Add rollback operation
209
+ this.operations.push({
210
+ type: 'copy',
211
+ source,
212
+ destination,
213
+ rollback: async () => {
214
+ try {
215
+ await fs.rm(destination, { recursive: true, force: true });
216
+ }
217
+ catch (error) {
218
+ logger.error(`[FileTransaction] Failed to rollback copy at ${destination}:`, error);
219
+ }
220
+ }
221
+ });
222
+ }
223
+ /**
224
+ * Add a delete operation to the transaction
225
+ */
226
+ async addDelete(path, backupPath) {
227
+ if (this.completed) {
228
+ throw new Error('Transaction already completed');
229
+ }
230
+ // If backup path provided, move instead of delete
231
+ if (backupPath) {
232
+ await fs.rename(path, backupPath);
233
+ this.operations.push({
234
+ type: 'delete',
235
+ source: path,
236
+ destination: backupPath,
237
+ rollback: async () => {
238
+ try {
239
+ await fs.rename(backupPath, path);
240
+ }
241
+ catch (error) {
242
+ logger.error(`[FileTransaction] Failed to restore deleted item from ${backupPath} to ${path}:`, error);
243
+ }
244
+ }
245
+ });
246
+ }
247
+ else {
248
+ // Direct delete (no rollback possible)
249
+ await fs.rm(path, { recursive: true, force: true });
250
+ this.operations.push({
251
+ type: 'delete',
252
+ source: path,
253
+ rollback: async () => {
254
+ logger.warn(`[FileTransaction] Cannot rollback permanent deletion of ${path}`);
255
+ }
256
+ });
257
+ }
258
+ }
259
+ /**
260
+ * Commit the transaction (mark as successful)
261
+ */
262
+ commit() {
263
+ this.completed = true;
264
+ }
265
+ /**
266
+ * Rollback all operations in reverse order
267
+ */
268
+ async rollback() {
269
+ logger.info(`[FileTransaction] Rolling back ${this.operations.length} operations`);
270
+ // Rollback in reverse order
271
+ for (let i = this.operations.length - 1; i >= 0; i--) {
272
+ const operation = this.operations[i];
273
+ logger.info(`[FileTransaction] Rolling back ${operation.type} operation`);
274
+ try {
275
+ await operation.rollback();
276
+ }
277
+ catch (error) {
278
+ logger.error(`[FileTransaction] Rollback failed for operation ${i}:`, error);
279
+ // Continue with other rollbacks
280
+ }
281
+ }
282
+ this.completed = true;
283
+ }
284
+ /**
285
+ * Check if any operations have been performed
286
+ */
287
+ hasOperations() {
288
+ return this.operations.length > 0;
289
+ }
290
+ }
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZU9wZXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvZmlsZU9wZXJhdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQWFyQzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUN6Qjs7O09BR0c7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FDeEIsR0FBVyxFQUNYLElBQVksRUFDWixVQUF1QixFQUFFO1FBRXpCLE1BQU0sRUFBRSxVQUFVLEVBQUUsZUFBZSxHQUFHLEVBQUUsRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDO1FBRXJFLHNEQUFzRDtRQUN0RCxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDdkUsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBRXBCLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUMvQixHQUFHLEVBQ0gsSUFBSSxFQUNKLGVBQWUsRUFDZixVQUFVLEVBQ1YsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNkLFdBQVcsRUFBRSxDQUFDO1lBQ2QsSUFBSSxVQUFVLEVBQUUsQ0FBQztnQkFDZixVQUFVLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNILENBQUMsQ0FDRixDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ssTUFBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FDMUMsR0FBVyxFQUNYLGVBQXlCO1FBRXpCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNuQixJQUFJLFNB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SSxFQUFFLENBQUMsQ0FBQztnQkFDakYsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO1FBQ0osSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDeEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFFBQVE7UUFDWixNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sYUFBYSxDQUFDLENBQUM7UUFFbkYsNEJBQTRCO1FBQzVCLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNyRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLFNBQVMsQ0FBQyxJQUFJLFlBQVksQ0FBQyxDQUFDO1lBRTFFLElBQUksQ0FBQztnQkFDSCxNQUFNLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM3QixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLENBQUMsS0FBSyxDQUFDLG1EQUFtRCxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDN0UsZ0NBQWdDO1lBQ2xDLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7SUFDeEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYTtRQUNYLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29weU9wdGlvbnMge1xuICBvblByb2dyZXNzPzogKGNvcGllZDogbnVtYmVyLCB0b3RhbDogbnVtYmVyLCBjdXJyZW50RmlsZTogc3RyaW5nKSA9PiB2b2lkO1xuICBleGNsdWRlUGF0dGVybnM/OiBzdHJpbmdbXTtcbiAgbWF4UmV0cmllcz86IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGaWxlU3RhdHMge1xuICB0b3RhbEZpbGVzOiBudW1iZXI7XG4gIHRvdGFsU2l6ZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIENyb3NzLXBsYXRmb3JtIGZpbGUgb3BlcmF0aW9ucyB1dGlsaXR5XG4gKiBDZW50cmFsaXplcyBjb21tb24gZmlsZSBvcGVyYXRpb25zIHdpdGggcHJvZ3Jlc3MgcmVwb3J0aW5nIGFuZCBlcnJvciBoYW5kbGluZ1xuICovXG5leHBvcnQgY2xhc3MgRmlsZU9wZXJhdGlvbnMge1xuICAvKipcbiAgICogUmVjdXJzaXZlbHkgY29weSBhIGRpcmVjdG9yeSB3aXRoIHByb2dyZXNzIHJlcG9ydGluZ1xuICAgKiBXb3JrcyBjcm9zcy1wbGF0Zm9ybSB3aXRob3V0IHJlbHlpbmcgb24gc2hlbGwgY29tbWFuZHNcbiAgICovXG4gIHN0YXRpYyBhc3luYyBjb3B5RGlyZWN0b3J5KFxuICAgIHNyYzogc3RyaW5nLCBcbiAgICBkZXN0OiBzdHJpbmcsIFxuICAgIG9wdGlvbnM6IENvcHlPcHRpb25zID0ge31cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBvblByb2dyZXNzLCBleGNsdWRlUGF0dGVybnMgPSBbXSwgbWF4UmV0cmllcyA9IDMgfSA9IG9wdGlvbnM7XG4gICAgXG4gICAgLy8gRmlyc3QsIGNhbGN1bGF0ZSB0b3RhbCBmaWxlcyBmb3IgcHJvZ3Jlc3MgcmVwb3J0aW5nXG4gICAgY29uc3Qgc3RhdHMgPSBhd2FpdCB0aGlzLmNhbGN1bGF0ZURpcmVjdG9yeVN0YXRzKHNyYywgZXhjbHVkZVBhdHRlcm5zKTtcbiAgICBsZXQgY29waWVkRmlsZXMgPSAwO1xuICAgIFxuICAgIGF3YWl0IHRoaXMuY29weURpcmVjdG9yeVJlY3Vyc2l2ZShcbiAgICAgIHNyYywgXG4gICAgICBkZXN0LCBcbiAgICAgIGV4Y2x1ZGVQYXR0ZXJucyxcbiAgICAgIG1heFJldHJpZXMsXG4gICAgICAoY3VycmVudEZpbGUpID0+IHtcbiAgICAgICAgY29waWVkRmlsZXMrKztcbiAgICAgICAgaWYgKG9uUHJvZ3Jlc3MpIHtcbiAgICAgICAgICBvblByb2dyZXNzKGNvcGllZEZpbGVzLCBzdGF0cy50b3RhbEZpbGVzLCBjdXJyZW50RmlsZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2FsY3VsYXRlIGRpcmVjdG9yeSBzdGF0aXN0aWNzIGZvciBwcm9ncmVzcyByZXBvcnRpbmdcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIGNhbGN1bGF0ZURpcmVjdG9yeVN0YXRzKFxuICAgIGRpcjogc3RyaW5nLFxuICAgIGV4Y2x1ZGVQYXR0ZXJuczogc3RyaW5nW11cbiAgKTogUHJvbWlzZTxGaWxlU3RhdHM+IHtcbiAgICBsZXQgdG90YWxGaWxlcyA9IDA7XG4gICAgbGV0IHRvdGFsU2l6ZSA9IDA7XG4gICAgXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBmcy5yZWFkZGlyKGRpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICAgICAgXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlyLCBlbnRyeS5uYW1lKTtcbiAgICAgICAgXG4gICAgICAgIC8vIFNraXAgZXhjbHVkZWQgcGF0dGVybnNcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkRXhjbHVkZShlbnRyeS5uYW1lLCBleGNsdWRlUGF0dGVybnMpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgY29uc3Qgc3ViU3RhdHMgPSBhd2FpdCB0aGlzLmNhbGN1bGF0ZURpcmVjdG9yeVN0YXRzKGZ1bGxQYXRoLCBleGNsdWRlUGF0dGVybnMpO1xuICAgICAgICAgIHRvdGFsRmlsZXMgKz0gc3ViU3RhdHMudG90YWxGaWxlcztcbiAgICAgICAgICB0b3RhbFNpemUgKz0gc3ViU3RhdHMudG90YWxTaXplO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRvdGFsRmlsZXMrKztcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdCA9IGF3YWl0IGZzLnN0YXQoZnVsbFBhdGgpO1xuICAgICAgICAgICAgdG90YWxTaXplICs9IHN0YXQuc2l6ZTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBzdGF0IGVycm9yc1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihgW0ZpbGVPcGVyYXRpb25zXSBFcnJvciBjYWxjdWxhdGluZyBzdGF0cyBmb3IgJHtkaXJ9OmAsIGVycm9yKTtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHsgdG90YWxGaWxlcywgdG90YWxTaXplIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBJbnRlcm5hbCByZWN1cnNpdmUgY29weSBpbXBsZW1lbnRhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgY29weURpcmVjdG9yeVJlY3Vyc2l2ZShcbiAgICBzcmM6IHN0cmluZyxcbiAgICBkZXN0OiBzdHJpbmcsXG4gICAgZXhjbHVkZVBhdHRlcm5zOiBzdHJpbmdbXSxcbiAgICBtYXhSZXRyaWVzOiBudW1iZXIsXG4gICAgb25GaWxlQ29waWVkOiAoZmlsZTogc3RyaW5nKSA9PiB2b2lkXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEVuc3VyZSBkZXN0aW5hdGlvbiBkaXJlY3RvcnkgZXhpc3RzXG4gICAgYXdhaXQgZnMubWtkaXIoZGVzdCwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgXG4gICAgY29uc3QgZW50cmllcyA9IGF3YWl0IGZzLnJlYWRkaXIoc3JjLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICBjb25zdCBzcmNQYXRoID0gcGF0aC5qb2luKHNyYywgZW50cnkubmFtZSk7XG4gICAgICBjb25zdCBkZXN0UGF0aCA9IHBhdGguam9pbihkZXN0LCBlbnRyeS5uYW1lKTtcbiAgICAgIFxuICAgICAgLy8gU2tpcCBleGNsdWRlZCBwYXR0ZXJuc1xuICAgICAgaWYgKHRoaXMuc2hvdWxkRXhjbHVkZShlbnRyeS5uYW1lLCBleGNsdWRlUGF0dGVybnMpKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgW0ZpbGVPcGVyYXRpb25zXSBTa2lwcGluZyBleGNsdWRlZDogJHtlbnRyeS5uYW1lfWApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb3B5RGlyZWN0b3J5UmVjdXJzaXZlKFxuICAgICAgICAgIHNyY1BhdGgsIFxuICAgICAgICAgIGRlc3RQYXRoLCBcbiAgICAgICAgICBleGNsdWRlUGF0dGVybnMsXG4gICAgICAgICAgbWF4UmV0cmllcyxcbiAgICAgICAgICBvbkZpbGVDb3BpZWRcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY29weUZpbGVXaXRoUmV0cnkoc3JjUGF0aCwgZGVzdFBhdGgsIG1heFJldHJpZXMpO1xuICAgICAgICBvbkZpbGVDb3BpZWQoc3JjUGF0aCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogQ29weSBhIHNpbmdsZSBmaWxlIHdpdGggcmV0cnkgbG9naWNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIGNvcHlGaWxlV2l0aFJldHJ5KFxuICAgIHNyYzogc3RyaW5nLFxuICAgIGRlc3Q6IHN0cmluZyxcbiAgICBtYXhSZXRyaWVzOiBudW1iZXJcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcbiAgICBcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzOyBhdHRlbXB0KyspIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGZzLmNvcHlGaWxlKHNyYywgZGVzdCk7XG4gICAgICAgIHJldHVybjsgLy8gU3VjY2Vzc1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbGFzdEVycm9yID0gZXJyb3IgYXMgRXJyb3I7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgW0ZpbGVPcGVyYXRpb25zXSBDb3B5IGF0dGVtcHQgJHthdHRlbXB0fSBmYWlsZWQgZm9yICR7c3JjfTogJHtlcnJvcn1gKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChhdHRlbXB0IDwgbWF4UmV0cmllcykge1xuICAgICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5IChleHBvbmVudGlhbCBiYWNrb2ZmKVxuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBNYXRoLnBvdygyLCBhdHRlbXB0KSAqIDEwMCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIC8vIEFsbCByZXRyaWVzIGZhaWxlZFxuICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGNvcHkgJHtzcmN9IGFmdGVyICR7bWF4UmV0cmllc30gYXR0ZW1wdHM6ICR7bGFzdEVycm9yPy5tZXNzYWdlfWApO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBmaWxlL2RpcmVjdG9yeSBzaG91bGQgYmUgZXhjbHVkZWRcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHNob3VsZEV4Y2x1ZGUobmFtZTogc3RyaW5nLCBwYXR0ZXJuczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IHBhdHRlcm4gb2YgcGF0dGVybnMpIHtcbiAgICAgIGlmIChwYXR0ZXJuLmluY2x1ZGVzKCcqJykpIHtcbiAgICAgICAgLy8gU2ltcGxlIGdsb2Igc3VwcG9ydFxuICAgICAgICBjb25zdCByZWdleCA9IG5ldyBSZWdFeHAoJ14nICsgcGF0dGVybi5yZXBsYWNlKC9cXCovZywgJy4qJykgKyAnJCcpO1xuICAgICAgICBpZiAocmVnZXgudGVzdChuYW1lKSkgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT09IHBhdHRlcm4pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIFJlbW92ZSBhIGRpcmVjdG9yeSB3aXRoIHByb2dyZXNzIHJlcG9ydGluZ1xuICAgKi9cbiAgc3RhdGljIGFzeW5jIHJlbW92ZURpcmVjdG9yeShcbiAgICBkaXI6IHN0cmluZyxcbiAgICBvcHRpb25zOiB7IG9uUHJvZ3Jlc3M/OiAocmVtb3ZlZDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKSA9PiB2b2lkIH0gPSB7fVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGF0cyA9IGF3YWl0IHRoaXMuY2FsY3VsYXRlRGlyZWN0b3J5U3RhdHMoZGlyLCBbXSk7XG4gICAgbGV0IHJlbW92ZWRGaWxlcyA9IDA7XG4gICAgXG4gICAgYXdhaXQgdGhpcy5yZW1vdmVEaXJlY3RvcnlSZWN1cnNpdmUoZGlyLCAoKSA9PiB7XG4gICAgICByZW1vdmVkRmlsZXMrKztcbiAgICAgIGlmIChvcHRpb25zLm9uUHJvZ3Jlc3MpIHtcbiAgICAgICAgb3B0aW9ucy5vblByb2dyZXNzKHJlbW92ZWRGaWxlcywgc3RhdHMudG90YWxGaWxlcyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBJbnRlcm5hbCByZWN1cnNpdmUgcmVtb3ZlIGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBhc3luYyByZW1vdmVEaXJlY3RvcnlSZWN1cnNpdmUoXG4gICAgZGlyOiBzdHJpbmcsXG4gICAgb25GaWxlUmVtb3ZlZDogKCkgPT4gdm9pZFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZW50cmllcyA9IGF3YWl0IGZzLnJlYWRkaXIoZGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgICBcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihkaXIsIGVudHJ5Lm5hbWUpO1xuICAgICAgICBcbiAgICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZURpcmVjdG9yeVJlY3Vyc2l2ZShmdWxsUGF0aCwgb25GaWxlUmVtb3ZlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgZnMudW5saW5rKGZ1bGxQYXRoKTtcbiAgICAgICAgICBvbkZpbGVSZW1vdmVkKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIFxuICAgICAgLy8gUmVtb3ZlIHRoZSBub3ctZW1wdHkgZGlyZWN0b3J5XG4gICAgICBhd2FpdCBmcy5ybWRpcihkaXIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYFtGaWxlT3BlcmF0aW9uc10gRXJyb3IgcmVtb3ZpbmcgZGlyZWN0b3J5ICR7ZGlyfTpgLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBDcmVhdGUgYSB0cmFuc2FjdGlvbiBtYW5hZ2VyIGZvciBhdG9taWMgZmlsZSBvcGVyYXRpb25zXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlVHJhbnNhY3Rpb24oKTogRmlsZVRyYW5zYWN0aW9uIHtcbiAgICByZXR1cm4gbmV3IEZpbGVUcmFuc2FjdGlvbigpO1xuICB9XG59XG5cbi8qKlxuICogVHJhbnNhY3Rpb24gbWFuYWdlciBmb3IgYXRvbWljIGZpbGUgb3BlcmF0aW9uc1xuICogRW5zdXJlcyBhbGwgb3BlcmF0aW9ucyBzdWNjZWVkIG9yIGFsbCBhcmUgcm9sbGVkIGJhY2tcbiAqL1xuZXhwb3J0IGNsYXNzIEZpbGVUcmFuc2FjdGlvbiB7XG4gIHByaXZhdGUgb3BlcmF0aW9uczogQXJyYXk8e1xuICAgIHR5cGU6ICdtb3ZlJyB8ICdjb3B5JyB8ICdkZWxldGUnIHwgJ2NyZWF0ZSc7XG4gICAgc291cmNlPzogc3RyaW5nO1xuICAgIGRlc3RpbmF0aW9uPzogc3RyaW5nO1xuICAgIHJvbGxiYWNrOiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICB9PiA9IFtdO1xuICBcbiAgcHJpdmF0ZSBjb21wbGV0ZWQgPSBmYWxzZTtcbiAgXG4gIC8qKlxuICAgKiBBZGQgYSBtb3ZlIG9wZXJhdGlvbiB0byB0aGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIGFzeW5jIGFkZE1vdmUoc291cmNlOiBzdHJpbmcsIGRlc3RpbmF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jb21wbGV0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNhY3Rpb24gYWxyZWFkeSBjb21wbGV0ZWQnKTtcbiAgICB9XG4gICAgXG4gICAgLy8gUGVyZm9ybSB0aGUgbW92ZVxuICAgIGF3YWl0IGZzLnJlbmFtZShzb3VyY2UsIGRlc3RpbmF0aW9uKTtcbiAgICBcbiAgICAvLyBBZGQgcm9sbGJhY2sgb3BlcmF0aW9uXG4gICAgdGhpcy5vcGVyYXRpb25zLnB1c2goe1xuICAgICAgdHlwZTogJ21vdmUnLFxuICAgICAgc291cmNlLFxuICAgICAgZGVzdGluYXRpb24sXG4gICAgICByb2xsYmFjazogYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGZzLnJlbmFtZShkZXN0aW5hdGlvbiwgc291cmNlKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYFtGaWxlVHJhbnNhY3Rpb25dIEZhaWxlZCB0byByb2xsYmFjayBtb3ZlIGZyb20gJHtkZXN0aW5hdGlvbn0gdG8gJHtzb3VyY2V9OmAsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogQWRkIGEgY29weSBvcGVyYXRpb24gdG8gdGhlIHRyYW5zYWN0aW9uXG4gICAqL1xuICBhc3luYyBhZGRDb3B5KHNvdXJjZTogc3RyaW5nLCBkZXN0aW5hdGlvbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY29tcGxldGVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zYWN0aW9uIGFscmVhZHkgY29tcGxldGVkJyk7XG4gICAgfVxuICAgIFxuICAgIC8vIFBlcmZvcm0gdGhlIGNvcHlcbiAgICBhd2FpdCBGaWxlT3BlcmF0aW9ucy5jb3B5RGlyZWN0b3J5KHNvdXJjZSwgZGVzdGluYXRpb24pO1xuICAgIFxuICAgIC8vIEFkZCByb2xsYmFjayBvcGVyYXRpb25cbiAgICB0aGlzLm9wZXJhdGlvbnMucHVzaCh7XG4gICAgICB0eXBlOiAnY29weScsXG4gICAgICBzb3VyY2UsXG4gICAgICBkZXN0aW5hdGlvbixcbiAgICAgIHJvbGxiYWNrOiBhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZnMucm0oZGVzdGluYXRpb24sIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYFtGaWxlVHJhbnNhY3Rpb25dIEZhaWxlZCB0byByb2xsYmFjayBjb3B5IGF0ICR7ZGVzdGluYXRpb259OmAsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIFxuICAvKipcbiAgICogQWRkIGEgZGVsZXRlIG9wZXJhdGlvbiB0byB0aGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIGFzeW5jIGFkZERlbGV0ZShwYXRoOiBzdHJpbmcsIGJhY2t1cFBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jb21wbGV0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNhY3Rpb24gYWxyZWFkeSBjb21wbGV0ZWQnKTtcbiAgICB9XG4gICAgXG4gICAgLy8gSWYgYmFja3VwIHBhdGggcHJvdmlkZWQsIG1vdmUgaW5zdGVhZCBvZiBkZWxldGVcbiAgICBpZiAoYmFja3VwUGF0aCkge1xuICAgICAgYXdhaXQgZnMucmVuYW1lKHBhdGgsIGJhY2t1cFBhdGgpO1xuICAgICAgXG4gICAgICB0aGlzLm9wZXJhdGlvbnMucHVzaCh7XG4gICAgICAgIHR5cGU6ICdkZWxldGUnLFxuICAgICAgICBzb3VyY2U6IHBhdGgsXG4gICAgICAgIGRlc3RpbmF0aW9uOiBiYWNrdXBQYXRoLFxuICAgICAgICByb2xsYmFjazogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBmcy5yZW5hbWUoYmFja3VwUGF0aCwgcGF0aCk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgW0ZpbGVUcmFuc2FjdGlvbl0gRmFpbGVkIHRvIHJlc3RvcmUgZGVsZXRlZCBpdGVtIGZyb20gJHtiYWNrdXBQYXRofSB0byAke3BhdGh9OmAsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEaXJlY3QgZGVsZXRlIChubyByb2xsYmFjayBwb3NzaWJsZSlcbiAgICAgIGF3YWl0IGZzLnJtKHBhdGgsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgIFxuICAgICAgdGhpcy5vcGVyYXRpb25zLnB1c2goe1xuICAgICAgICB0eXBlOiAnZGVsZXRlJyxcbiAgICAgICAgc291cmNlOiBwYXRoLFxuICAgICAgICByb2xsYmFjazogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGxvZ2dlci53YXJuKGBbRmlsZVRyYW5zYWN0aW9uXSBDYW5ub3Qgcm9sbGJhY2sgcGVybWFuZW50IGRlbGV0aW9uIG9mICR7cGF0aH1gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIFxuICAvKipcbiAgICogQ29tbWl0IHRoZSB0cmFuc2FjdGlvbiAobWFyayBhcyBzdWNjZXNzZnVsKVxuICAgKi9cbiAgY29tbWl0KCk6IHZvaWQge1xuICAgIHRoaXMuY29tcGxldGVkID0gdHJ1ZTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIFJvbGxiYWNrIGFsbCBvcGVyYXRpb25zIGluIHJldmVyc2Ugb3JkZXJcbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZ2dlci5pbmZvKGBbRmlsZVRyYW5zYWN0aW9uXSBSb2xsaW5nIGJhY2sgJHt0aGlzLm9wZXJhdGlvbnMubGVuZ3RofSBvcGVyYXRpb25zYCk7XG4gICAgXG4gICAgLy8gUm9sbGJhY2sgaW4gcmV2ZXJzZSBvcmRlclxuICAgIGZvciAobGV0IGkgPSB0aGlzLm9wZXJhdGlvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IHRoaXMub3BlcmF0aW9uc1tpXTtcbiAgICAgIGxvZ2dlci5pbmZvKGBbRmlsZVRyYW5zYWN0aW9uXSBSb2xsaW5nIGJhY2sgJHtvcGVyYXRpb24udHlwZX0gb3BlcmF0aW9uYCk7XG4gICAgICBcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IG9wZXJhdGlvbi5yb2xsYmFjaygpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBbRmlsZVRyYW5zYWN0aW9uXSBSb2xsYmFjayBmYWlsZWQgZm9yIG9wZXJhdGlvbiAke2l9OmAsIGVycm9yKTtcbiAgICAgICAgLy8gQ29udGludWUgd2l0aCBvdGhlciByb2xsYmFja3NcbiAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgdGhpcy5jb21wbGV0ZWQgPSB0cnVlO1xuICB9XG4gIFxuICAvKipcbiAgICogQ2hlY2sgaWYgYW55IG9wZXJhdGlvbnMgaGF2ZSBiZWVuIHBlcmZvcm1lZFxuICAgKi9cbiAgaGFzT3BlcmF0aW9ucygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5vcGVyYXRpb25zLmxlbmd0aCA+IDA7XG4gIH1cbn0iXX0=
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Installation detection utilities
3
+ * Determines whether the application is running from npm or git installation
4
+ */
5
+ export type InstallationType = 'npm' | 'git' | 'unknown';
6
+ export declare class InstallationDetector {
7
+ private static cachedType;
8
+ private static get MAX_SEARCH_DEPTH();
9
+ /**
10
+ * Detect the installation type (npm global, git clone, or unknown)
11
+ */
12
+ static getInstallationType(): InstallationType;
13
+ /**
14
+ * Get the npm global installation path if running from npm
15
+ */
16
+ static getNpmGlobalPath(): string | null;
17
+ /**
18
+ * Get the git repository root path if running from git
19
+ */
20
+ static getGitRepositoryPath(): string | null;
21
+ /**
22
+ * Get a human-readable description of the installation
23
+ */
24
+ static getInstallationDescription(): string;
25
+ /**
26
+ * Clear the cached installation type (mainly for testing)
27
+ */
28
+ static clearCache(): void;
29
+ }
30
+ //# sourceMappingURL=installation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../src/utils/installation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAEzD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAiC;IAG1D,OAAO,CAAC,MAAM,KAAK,gBAAgB,GAElC;IAED;;OAEG;IACH,MAAM,CAAC,mBAAmB,IAAI,gBAAgB;IA8D9C;;OAEG;IACH,MAAM,CAAC,gBAAgB,IAAI,MAAM,GAAG,IAAI;IA2BxC;;OAEG;IACH,MAAM,CAAC,oBAAoB,IAAI,MAAM,GAAG,IAAI;IA4B5C;;OAEG;IACH,MAAM,CAAC,0BAA0B,IAAI,MAAM;IAqB3C;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;CAG1B"}