devports 0.0.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/LICENSE +21 -0
  3. package/README.md +810 -29
  4. package/dist/cli.d.ts +7 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +329 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/allocate.command.d.ts +8 -0
  9. package/dist/commands/allocate.command.d.ts.map +1 -0
  10. package/dist/commands/allocate.command.js +84 -0
  11. package/dist/commands/allocate.command.js.map +1 -0
  12. package/dist/commands/base-command.d.ts +28 -0
  13. package/dist/commands/base-command.d.ts.map +1 -0
  14. package/dist/commands/base-command.js +33 -0
  15. package/dist/commands/base-command.js.map +1 -0
  16. package/dist/commands/check.command.d.ts +7 -0
  17. package/dist/commands/check.command.d.ts.map +1 -0
  18. package/dist/commands/check.command.js +44 -0
  19. package/dist/commands/check.command.js.map +1 -0
  20. package/dist/commands/completion.command.d.ts +7 -0
  21. package/dist/commands/completion.command.d.ts.map +1 -0
  22. package/dist/commands/completion.command.js +116 -0
  23. package/dist/commands/completion.command.js.map +1 -0
  24. package/dist/commands/gitignore.command.d.ts +7 -0
  25. package/dist/commands/gitignore.command.d.ts.map +1 -0
  26. package/dist/commands/gitignore.command.js +61 -0
  27. package/dist/commands/gitignore.command.js.map +1 -0
  28. package/dist/commands/index.d.ts +7 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +35 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/info.command.d.ts +7 -0
  33. package/dist/commands/info.command.d.ts.map +1 -0
  34. package/dist/commands/info.command.js +40 -0
  35. package/dist/commands/info.command.js.map +1 -0
  36. package/dist/commands/list.command.d.ts +8 -0
  37. package/dist/commands/list.command.d.ts.map +1 -0
  38. package/dist/commands/list.command.js +165 -0
  39. package/dist/commands/list.command.js.map +1 -0
  40. package/dist/commands/release.command.d.ts +8 -0
  41. package/dist/commands/release.command.d.ts.map +1 -0
  42. package/dist/commands/release.command.js +89 -0
  43. package/dist/commands/release.command.js.map +1 -0
  44. package/dist/commands/render.command.d.ts +7 -0
  45. package/dist/commands/render.command.d.ts.map +1 -0
  46. package/dist/commands/render.command.js +53 -0
  47. package/dist/commands/render.command.js.map +1 -0
  48. package/dist/commands/reserve.command.d.ts +7 -0
  49. package/dist/commands/reserve.command.d.ts.map +1 -0
  50. package/dist/commands/reserve.command.js +42 -0
  51. package/dist/commands/reserve.command.js.map +1 -0
  52. package/dist/commands/setup.command.d.ts +7 -0
  53. package/dist/commands/setup.command.d.ts.map +1 -0
  54. package/dist/commands/setup.command.js +43 -0
  55. package/dist/commands/setup.command.js.map +1 -0
  56. package/dist/commands/status.command.d.ts +7 -0
  57. package/dist/commands/status.command.d.ts.map +1 -0
  58. package/dist/commands/status.command.js +41 -0
  59. package/dist/commands/status.command.js.map +1 -0
  60. package/dist/commands/unreserve.command.d.ts +7 -0
  61. package/dist/commands/unreserve.command.d.ts.map +1 -0
  62. package/dist/commands/unreserve.command.js +38 -0
  63. package/dist/commands/unreserve.command.js.map +1 -0
  64. package/dist/commands/worktree-add.command.d.ts +7 -0
  65. package/dist/commands/worktree-add.command.d.ts.map +1 -0
  66. package/dist/commands/worktree-add.command.js +68 -0
  67. package/dist/commands/worktree-add.command.js.map +1 -0
  68. package/dist/commands/worktree-remove.command.d.ts +7 -0
  69. package/dist/commands/worktree-remove.command.d.ts.map +1 -0
  70. package/dist/commands/worktree-remove.command.js +33 -0
  71. package/dist/commands/worktree-remove.command.js.map +1 -0
  72. package/dist/completion/bash-completion-template.d.ts +5 -0
  73. package/dist/completion/bash-completion-template.d.ts.map +1 -0
  74. package/dist/completion/bash-completion-template.js +14 -0
  75. package/dist/completion/bash-completion-template.js.map +1 -0
  76. package/dist/completion/bash.sh +208 -0
  77. package/dist/completion/completion-data.d.ts +16 -0
  78. package/dist/completion/completion-data.d.ts.map +1 -0
  79. package/dist/completion/completion-data.js +38 -0
  80. package/dist/completion/completion-data.js.map +1 -0
  81. package/dist/completion/index.d.ts +24 -0
  82. package/dist/completion/index.d.ts.map +1 -0
  83. package/dist/completion/index.js +30 -0
  84. package/dist/completion/index.js.map +1 -0
  85. package/dist/completion/shell-config.d.ts +27 -0
  86. package/dist/completion/shell-config.d.ts.map +1 -0
  87. package/dist/completion/shell-config.js +243 -0
  88. package/dist/completion/shell-config.js.map +1 -0
  89. package/dist/completion/zsh-completion-template.d.ts +5 -0
  90. package/dist/completion/zsh-completion-template.d.ts.map +1 -0
  91. package/dist/completion/zsh-completion-template.js +14 -0
  92. package/dist/completion/zsh-completion-template.js.map +1 -0
  93. package/dist/completion/zsh.sh +164 -0
  94. package/dist/config.d.ts +6 -0
  95. package/dist/config.d.ts.map +1 -0
  96. package/dist/config.js +111 -0
  97. package/dist/config.js.map +1 -0
  98. package/dist/devports-1.0.0.tgz +0 -0
  99. package/dist/execution.d.ts +31 -0
  100. package/dist/execution.d.ts.map +1 -0
  101. package/dist/execution.js +110 -0
  102. package/dist/execution.js.map +1 -0
  103. package/dist/gitignore.d.ts +22 -0
  104. package/dist/gitignore.d.ts.map +1 -0
  105. package/dist/gitignore.js +142 -0
  106. package/dist/gitignore.js.map +1 -0
  107. package/dist/index.d.ts +7 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/index.js +6 -0
  110. package/dist/index.js.map +1 -0
  111. package/dist/port-manager.d.ts +33 -0
  112. package/dist/port-manager.d.ts.map +1 -0
  113. package/dist/port-manager.js +169 -0
  114. package/dist/port-manager.js.map +1 -0
  115. package/dist/port-utils.d.ts +9 -0
  116. package/dist/port-utils.d.ts.map +1 -0
  117. package/dist/port-utils.js +38 -0
  118. package/dist/port-utils.js.map +1 -0
  119. package/dist/render.d.ts +54 -0
  120. package/dist/render.d.ts.map +1 -0
  121. package/dist/render.js +286 -0
  122. package/dist/render.js.map +1 -0
  123. package/dist/services/lock-manager.d.ts +46 -0
  124. package/dist/services/lock-manager.d.ts.map +1 -0
  125. package/dist/services/lock-manager.js +118 -0
  126. package/dist/services/lock-manager.js.map +1 -0
  127. package/dist/services/response-formatter.d.ts +45 -0
  128. package/dist/services/response-formatter.d.ts.map +1 -0
  129. package/dist/services/response-formatter.js +102 -0
  130. package/dist/services/response-formatter.js.map +1 -0
  131. package/dist/services/validation-service.d.ts +109 -0
  132. package/dist/services/validation-service.d.ts.map +1 -0
  133. package/dist/services/validation-service.js +267 -0
  134. package/dist/services/validation-service.js.map +1 -0
  135. package/dist/setup.d.ts +20 -0
  136. package/dist/setup.d.ts.map +1 -0
  137. package/dist/setup.js +243 -0
  138. package/dist/setup.js.map +1 -0
  139. package/dist/types.d.ts +29 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +18 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/validation.d.ts +69 -0
  144. package/dist/validation.d.ts.map +1 -0
  145. package/dist/validation.js +344 -0
  146. package/dist/validation.js.map +1 -0
  147. package/dist/worktree.d.ts +24 -0
  148. package/dist/worktree.d.ts.map +1 -0
  149. package/dist/worktree.js +245 -0
  150. package/dist/worktree.js.map +1 -0
  151. package/package.json +90 -6
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Lock management service for coordinating file access
3
+ * Abstracts the common lock/unlock patterns used throughout the application
4
+ */
5
+ import type { Registry } from '../types.js';
6
+ /**
7
+ * Configuration for lock operations
8
+ */
9
+ export interface LockOptions {
10
+ retries?: number;
11
+ stale?: number;
12
+ }
13
+ /**
14
+ * Operation result that controls whether registry is saved
15
+ */
16
+ export interface RegistryOperationResult<T> {
17
+ result: T;
18
+ shouldSave?: boolean;
19
+ }
20
+ /**
21
+ * Lock manager for coordinating registry file access
22
+ * Ensures thread-safe operations on the port registry
23
+ */
24
+ export declare class LockManager {
25
+ /**
26
+ * Execute an operation with exclusive access to the registry file
27
+ * Handles the complete lock/load/save/unlock cycle
28
+ */
29
+ static withRegistryLock<T>(operation: (registry: Registry) => Promise<T> | T, options?: LockOptions): Promise<T>;
30
+ /**
31
+ * Execute an operation with conditional saving
32
+ * Save registry only if the operation indicates it should be saved
33
+ */
34
+ static withRegistryLockConditional<T>(operation: (registry: Registry) => Promise<RegistryOperationResult<T>> | RegistryOperationResult<T>, options?: LockOptions): Promise<T>;
35
+ /**
36
+ * Execute a read-only operation with shared access to the registry
37
+ * Loads registry without saving changes
38
+ */
39
+ static withRegistryReadLock<T>(operation: (registry: Registry) => Promise<T> | T, options?: LockOptions): Promise<T>;
40
+ /**
41
+ * Execute an operation with a custom file lock
42
+ * Generic lock manager for other file operations
43
+ */
44
+ static withFileLock<T>(filePath: string, operation: () => Promise<T> | T, options?: LockOptions): Promise<T>;
45
+ }
46
+ //# sourceMappingURL=lock-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-manager.d.ts","sourceRoot":"","sources":["../../src/services/lock-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,WAAW;IACtB;;;OAGG;WACU,gBAAgB,CAAC,CAAC,EAC7B,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACjD,OAAO,GAAE,WAAkC,GAC1C,OAAO,CAAC,CAAC,CAAC;IA6Bb;;;OAGG;WACU,2BAA2B,CAAC,CAAC,EACxC,SAAS,EAAE,CACT,QAAQ,EAAE,QAAQ,KACf,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,EACrE,OAAO,GAAE,WAAkC,GAC1C,OAAO,CAAC,CAAC,CAAC;IA+Bb;;;OAGG;WACU,oBAAoB,CAAC,CAAC,EACjC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACjD,OAAO,GAAE,WAAkC,GAC1C,OAAO,CAAC,CAAC,CAAC;IA2Bb;;;OAGG;WACU,YAAY,CAAC,CAAC,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAC/B,OAAO,GAAE,WAAkC,GAC1C,OAAO,CAAC,CAAC,CAAC;CAYd"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Lock management service for coordinating file access
3
+ * Abstracts the common lock/unlock patterns used throughout the application
4
+ */
5
+ import lockfile from 'proper-lockfile';
6
+ import { loadConfig, loadRegistry, saveRegistry } from '../config.js';
7
+ /**
8
+ * Default lock options used throughout the application
9
+ */
10
+ const DEFAULT_LOCK_OPTIONS = {
11
+ retries: 5,
12
+ stale: 10000,
13
+ };
14
+ /**
15
+ * Lock manager for coordinating registry file access
16
+ * Ensures thread-safe operations on the port registry
17
+ */
18
+ export class LockManager {
19
+ /**
20
+ * Execute an operation with exclusive access to the registry file
21
+ * Handles the complete lock/load/save/unlock cycle
22
+ */
23
+ static async withRegistryLock(operation, options = DEFAULT_LOCK_OPTIONS) {
24
+ const config = loadConfig();
25
+ // Ensure registry exists before locking
26
+ loadRegistry();
27
+ // Lock the registry file
28
+ const release = await lockfile.lock(config.registryPath, {
29
+ retries: options.retries,
30
+ stale: options.stale,
31
+ });
32
+ try {
33
+ // Load fresh registry data while holding the lock
34
+ const registry = loadRegistry();
35
+ // Execute the operation with the registry
36
+ const result = await operation(registry);
37
+ // Save the registry after the operation
38
+ saveRegistry(registry);
39
+ return result;
40
+ }
41
+ finally {
42
+ // Always release the lock
43
+ await release();
44
+ }
45
+ }
46
+ /**
47
+ * Execute an operation with conditional saving
48
+ * Save registry only if the operation indicates it should be saved
49
+ */
50
+ static async withRegistryLockConditional(operation, options = DEFAULT_LOCK_OPTIONS) {
51
+ const config = loadConfig();
52
+ // Ensure registry exists before locking
53
+ loadRegistry();
54
+ // Lock the registry file
55
+ const release = await lockfile.lock(config.registryPath, {
56
+ retries: options.retries,
57
+ stale: options.stale,
58
+ });
59
+ try {
60
+ // Load fresh registry data while holding the lock
61
+ const registry = loadRegistry();
62
+ // Execute the operation with the registry
63
+ const operationResult = await operation(registry);
64
+ // Save the registry only if requested
65
+ if (operationResult.shouldSave !== false) {
66
+ saveRegistry(registry);
67
+ }
68
+ return operationResult.result;
69
+ }
70
+ finally {
71
+ // Always release the lock
72
+ await release();
73
+ }
74
+ }
75
+ /**
76
+ * Execute a read-only operation with shared access to the registry
77
+ * Loads registry without saving changes
78
+ */
79
+ static async withRegistryReadLock(operation, options = DEFAULT_LOCK_OPTIONS) {
80
+ const config = loadConfig();
81
+ // Ensure registry exists before locking
82
+ loadRegistry();
83
+ // Lock the registry file (even for reads to ensure consistency)
84
+ const release = await lockfile.lock(config.registryPath, {
85
+ retries: options.retries,
86
+ stale: options.stale,
87
+ });
88
+ try {
89
+ // Load fresh registry data while holding the lock
90
+ const registry = loadRegistry();
91
+ // Execute the read-only operation
92
+ const result = await operation(registry);
93
+ // No need to save for read-only operations
94
+ return result;
95
+ }
96
+ finally {
97
+ // Always release the lock
98
+ await release();
99
+ }
100
+ }
101
+ /**
102
+ * Execute an operation with a custom file lock
103
+ * Generic lock manager for other file operations
104
+ */
105
+ static async withFileLock(filePath, operation, options = DEFAULT_LOCK_OPTIONS) {
106
+ const release = await lockfile.lock(filePath, {
107
+ retries: options.retries,
108
+ stale: options.stale,
109
+ });
110
+ try {
111
+ return await operation();
112
+ }
113
+ finally {
114
+ await release();
115
+ }
116
+ }
117
+ }
118
+ //# sourceMappingURL=lock-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-manager.js","sourceRoot":"","sources":["../../src/services/lock-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAWtE;;GAEG;AACH,MAAM,oBAAoB,GAAgB;IACxC,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,KAAK;CACb,CAAC;AAUF;;;GAGG;AACH,MAAM,OAAO,WAAW;IACtB;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAC3B,SAAiD,EACjD,UAAuB,oBAAoB;QAE3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,wCAAwC;QACxC,YAAY,EAAE,CAAC;QAEf,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;YACvD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,kDAAkD;YAClD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;YAEhC,0CAA0C;YAC1C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;YAEzC,wCAAwC;YACxC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAEvB,OAAO,MAAM,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,0BAA0B;YAC1B,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,2BAA2B,CACtC,SAEqE,EACrE,UAAuB,oBAAoB;QAE3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,wCAAwC;QACxC,YAAY,EAAE,CAAC;QAEf,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;YACvD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,kDAAkD;YAClD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;YAEhC,0CAA0C;YAC1C,MAAM,eAAe,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;YAElD,sCAAsC;YACtC,IAAI,eAAe,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;gBACzC,YAAY,CAAC,QAAQ,CAAC,CAAC;YACzB,CAAC;YAED,OAAO,eAAe,CAAC,MAAM,CAAC;QAChC,CAAC;gBAAS,CAAC;YACT,0BAA0B;YAC1B,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAC/B,SAAiD,EACjD,UAAuB,oBAAoB;QAE3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,wCAAwC;QACxC,YAAY,EAAE,CAAC;QAEf,gEAAgE;QAChE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;YACvD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,kDAAkD;YAClD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;YAEhC,kCAAkC;YAClC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;YAEzC,2CAA2C;YAC3C,OAAO,MAAM,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,0BAA0B;YAC1B,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,QAAgB,EAChB,SAA+B,EAC/B,UAAuB,oBAAoB;QAE3C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE;YAC5C,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Response formatter service - centralizes JSON/console output patterns
3
+ * Consolidates the repeated logic across all commands for DRY compliance
4
+ */
5
+ export interface ResponseOptions {
6
+ json?: boolean;
7
+ quiet?: boolean;
8
+ }
9
+ export interface ResponseData {
10
+ success: boolean;
11
+ message?: string;
12
+ data?: unknown;
13
+ }
14
+ export declare class ResponseFormatter {
15
+ /**
16
+ * Format and output a response based on options
17
+ * Handles both JSON and console output patterns
18
+ */
19
+ static format(response: ResponseData, options?: ResponseOptions): ResponseData;
20
+ /**
21
+ * Format success response with message
22
+ */
23
+ static success(message: string, data?: unknown): ResponseData;
24
+ /**
25
+ * Format error response with message
26
+ */
27
+ static error(message: string, data?: unknown): ResponseData;
28
+ /**
29
+ * Format data-only response (for list operations, etc.)
30
+ */
31
+ static data(data: unknown, message?: string): ResponseData;
32
+ /**
33
+ * Handle quiet-specific output (like port numbers only)
34
+ */
35
+ static quiet(value: string | number, data?: unknown): ResponseData;
36
+ /**
37
+ * Format port allocation response (common pattern)
38
+ */
39
+ static portAllocation(port: number, project: string, service: string, type?: string): ResponseData;
40
+ /**
41
+ * Format port release response (common pattern)
42
+ */
43
+ static portRelease(count: number, target?: string): ResponseData;
44
+ }
45
+ //# sourceMappingURL=response-formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-formatter.d.ts","sourceRoot":"","sources":["../../src/services/response-formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,iBAAiB;IAC5B;;;OAGG;IACH,MAAM,CAAC,MAAM,CACX,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,eAAoB,GAC5B,YAAY;IAwBf;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,YAAY;IAQ7D;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,YAAY;IAQ3D;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY;IAQ1D;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,YAAY;IAQlE;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,GACZ,YAAY;IAiBf;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;CAYjE"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Response formatter service - centralizes JSON/console output patterns
3
+ * Consolidates the repeated logic across all commands for DRY compliance
4
+ */
5
+ export class ResponseFormatter {
6
+ /**
7
+ * Format and output a response based on options
8
+ * Handles both JSON and console output patterns
9
+ */
10
+ static format(response, options = {}) {
11
+ if (options.json) {
12
+ // JSON output - consistent across all commands
13
+ const jsonData = response.data ?? {
14
+ success: response.success,
15
+ message: response.message,
16
+ };
17
+ console.log(JSON.stringify(jsonData, null, 2));
18
+ return response;
19
+ }
20
+ if (options.quiet) {
21
+ // Quiet mode - minimal or no output
22
+ return response;
23
+ }
24
+ // Console output - show message if present
25
+ if (response.message) {
26
+ console.log(response.message);
27
+ }
28
+ return response;
29
+ }
30
+ /**
31
+ * Format success response with message
32
+ */
33
+ static success(message, data) {
34
+ return {
35
+ success: true,
36
+ message,
37
+ data,
38
+ };
39
+ }
40
+ /**
41
+ * Format error response with message
42
+ */
43
+ static error(message, data) {
44
+ return {
45
+ success: false,
46
+ message,
47
+ data,
48
+ };
49
+ }
50
+ /**
51
+ * Format data-only response (for list operations, etc.)
52
+ */
53
+ static data(data, message) {
54
+ return {
55
+ success: true,
56
+ data,
57
+ message,
58
+ };
59
+ }
60
+ /**
61
+ * Handle quiet-specific output (like port numbers only)
62
+ */
63
+ static quiet(value, data) {
64
+ console.log(value);
65
+ return {
66
+ success: true,
67
+ data,
68
+ };
69
+ }
70
+ /**
71
+ * Format port allocation response (common pattern)
72
+ */
73
+ static portAllocation(port, project, service, type) {
74
+ const message = `✅ Allocated port ${port} for ${project}/${service}`;
75
+ const data = {
76
+ port,
77
+ project,
78
+ service,
79
+ type,
80
+ allocatedAt: new Date().toISOString(),
81
+ };
82
+ return {
83
+ success: true,
84
+ message,
85
+ data,
86
+ };
87
+ }
88
+ /**
89
+ * Format port release response (common pattern)
90
+ */
91
+ static portRelease(count, target) {
92
+ const message = count > 0
93
+ ? `✅ Released ${count} port(s)${target ? ` for ${target}` : ''}`
94
+ : `⚠️ No ports found${target ? ` for ${target}` : ''}`;
95
+ return {
96
+ success: count > 0,
97
+ message,
98
+ data: { releasedCount: count },
99
+ };
100
+ }
101
+ }
102
+ //# sourceMappingURL=response-formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-formatter.js","sourceRoot":"","sources":["../../src/services/response-formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,OAAO,iBAAiB;IAC5B;;;OAGG;IACH,MAAM,CAAC,MAAM,CACX,QAAsB,EACtB,UAA2B,EAAE;QAE7B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,+CAA+C;YAC/C,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,IAAI;gBAChC,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;aAC1B,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,oCAAoC;YACpC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,2CAA2C;QAC3C,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAe,EAAE,IAAc;QAC5C,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO;YACP,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAe,EAAE,IAAc;QAC1C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,OAAO;YACP,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,IAAa,EAAE,OAAgB;QACzC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI;YACJ,OAAO;SACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,KAAsB,EAAE,IAAc;QACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,IAAY,EACZ,OAAe,EACf,OAAe,EACf,IAAa;QAEb,MAAM,OAAO,GAAG,oBAAoB,IAAI,QAAQ,OAAO,IAAI,OAAO,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,OAAO;YACP,OAAO;YACP,IAAI;YACJ,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO;YACP,IAAI;SACL,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAa,EAAE,MAAe;QAC/C,MAAM,OAAO,GACX,KAAK,GAAG,CAAC;YACP,CAAC,CAAC,cAAc,KAAK,WAAW,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;YAChE,CAAC,CAAC,qBAAqB,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAE5D,OAAO;YACL,OAAO,EAAE,KAAK,GAAG,CAAC;YAClB,OAAO;YACP,IAAI,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE;SAC/B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Consolidated validation service - eliminates duplication in validation logic
3
+ * Implements configurable validation patterns for DRY compliance
4
+ */
5
+ export declare class ValidationError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ /**
9
+ * Configuration for string validation
10
+ */
11
+ export interface StringValidationConfig {
12
+ name: string;
13
+ maxLength?: number;
14
+ minLength?: number;
15
+ pattern?: RegExp;
16
+ disallowedPrefixes?: string[];
17
+ required?: boolean;
18
+ customErrorMessage?: string;
19
+ }
20
+ /**
21
+ * Configuration for path validation
22
+ */
23
+ export interface PathValidationConfig {
24
+ name: string;
25
+ mustExist?: boolean;
26
+ allowRelative?: boolean;
27
+ allowedExtensions?: string[];
28
+ maxLength?: number;
29
+ customErrorMessage?: string;
30
+ }
31
+ /**
32
+ * Configuration for numeric validation
33
+ */
34
+ export interface NumericValidationConfig {
35
+ name: string;
36
+ min?: number;
37
+ max?: number;
38
+ integer?: boolean;
39
+ required?: boolean;
40
+ customErrorMessage?: string;
41
+ }
42
+ /**
43
+ * Common validation patterns
44
+ */
45
+ export declare const ValidationPatterns: {
46
+ readonly PROJECT_SERVICE: RegExp;
47
+ readonly BRANCH_NAME: RegExp;
48
+ readonly SAFE_PATH: RegExp;
49
+ readonly SHELL_DANGEROUS: RegExp;
50
+ };
51
+ /**
52
+ * Predefined validation configurations for common use cases
53
+ */
54
+ export declare const ValidationConfigs: {
55
+ readonly PROJECT_NAME: StringValidationConfig;
56
+ readonly SERVICE_NAME: StringValidationConfig;
57
+ readonly BRANCH_NAME: StringValidationConfig;
58
+ readonly PORT_NUMBER: NumericValidationConfig;
59
+ readonly TEMPLATE_PATH: PathValidationConfig;
60
+ readonly WORKTREE_PATH: PathValidationConfig;
61
+ readonly OUTPUT_PATH: PathValidationConfig;
62
+ };
63
+ /**
64
+ * Centralized validation service with configurable validators
65
+ */
66
+ export declare class ValidationService {
67
+ /**
68
+ * Validate a string value with configurable rules
69
+ */
70
+ static validateString(value: string, config: StringValidationConfig): string;
71
+ /**
72
+ * Validate a numeric value with configurable rules
73
+ */
74
+ static validateNumber(value: string | number, config: NumericValidationConfig): number;
75
+ /**
76
+ * Validate a path with configurable rules
77
+ */
78
+ static validatePath(value: string, config: PathValidationConfig): string;
79
+ /**
80
+ * Convenience methods using predefined configurations
81
+ */
82
+ static validateProjectName(value: string): string;
83
+ static validateServiceName(value: string): string;
84
+ static validateBranchName(value: string): string;
85
+ static validatePort(value: string | number): number;
86
+ static validateTemplatePath(value: string): string;
87
+ static validateWorktreePath(value: string): string;
88
+ static validateOutputPath(value: string): string;
89
+ /**
90
+ * Validate service type against allowed types
91
+ */
92
+ static validateServiceType(type: string): string;
93
+ /**
94
+ * Validate script file path for post-hooks and similar
95
+ */
96
+ static validateScriptPath(path: string): string;
97
+ /**
98
+ * Validate an array of service definitions in "service" or "service:type" format
99
+ */
100
+ static validateServices(services: string[]): Array<{
101
+ service: string;
102
+ type: string;
103
+ }>;
104
+ /**
105
+ * Sanitize string for safe display/logging, removing dangerous characters
106
+ */
107
+ static sanitizeForDisplay(input: string, maxLength?: number): string;
108
+ }
109
+ //# sourceMappingURL=validation-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-service.d.ts","sourceRoot":"","sources":["../../src/services/validation-service.ts"],"names":[],"mappings":"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"}