@mks2508/better-logger 5.0.1 → 5.0.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 (310) hide show
  1. package/dist/Logger.d.ts +976 -0
  2. package/dist/Logger.d.ts.map +1 -0
  3. package/dist/ScopedLogger.d.ts +74 -0
  4. package/dist/ScopedLogger.d.ts.map +1 -0
  5. package/dist/chunks/Logger-CKqzXDh3.js +2 -0
  6. package/dist/chunks/Logger-CKqzXDh3.js.map +1 -0
  7. package/dist/chunks/Logger-D_vuKP4l.js +4511 -0
  8. package/dist/chunks/Logger-D_vuKP4l.js.map +1 -0
  9. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js +33 -0
  10. package/dist/chunks/RemoteLogHandler-CjWpWZGl.js.map +1 -0
  11. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js +2 -0
  12. package/dist/chunks/RemoteLogHandler-ymkQ97xl.js.map +1 -0
  13. package/dist/chunks/cli-module-B-njrTWb.js +2 -0
  14. package/dist/chunks/cli-module-B-njrTWb.js.map +1 -0
  15. package/dist/chunks/cli-module-Cx7qotPY.js +390 -0
  16. package/dist/chunks/cli-module-Cx7qotPY.js.map +1 -0
  17. package/dist/chunks/color-converter-CCSQRztd.js +2 -0
  18. package/dist/chunks/color-converter-CCSQRztd.js.map +1 -0
  19. package/dist/chunks/color-converter-_Xdmsy7E.js +462 -0
  20. package/dist/chunks/color-converter-_Xdmsy7E.js.map +1 -0
  21. package/dist/chunks/environment-C1xxvc8l.js +1127 -0
  22. package/dist/chunks/environment-C1xxvc8l.js.map +1 -0
  23. package/dist/chunks/environment-Cprkw3g9.js +4 -0
  24. package/dist/chunks/environment-Cprkw3g9.js.map +1 -0
  25. package/dist/chunks/formatting-DMJxYq9o.js +380 -0
  26. package/dist/chunks/formatting-DMJxYq9o.js.map +1 -0
  27. package/dist/chunks/formatting-DpKxCsXq.js +2 -0
  28. package/dist/chunks/formatting-DpKxCsXq.js.map +1 -0
  29. package/dist/cli/CommandProcessor.d.ts +100 -0
  30. package/dist/cli/CommandProcessor.d.ts.map +1 -0
  31. package/dist/cli/commands/ConfigCommand.d.ts +14 -0
  32. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
  33. package/dist/cli/commands/ExportCommand.d.ts +48 -0
  34. package/dist/cli/commands/ExportCommand.d.ts.map +1 -0
  35. package/dist/cli/commands/HistoryCommand.d.ts +47 -0
  36. package/dist/cli/commands/HistoryCommand.d.ts.map +1 -0
  37. package/dist/cli/commands/StatusCommand.d.ts +30 -0
  38. package/dist/cli/commands/StatusCommand.d.ts.map +1 -0
  39. package/dist/cli/commands/ThemeCommand.d.ts +30 -0
  40. package/dist/cli/commands/ThemeCommand.d.ts.map +1 -0
  41. package/dist/cli/help.d.ts +12 -0
  42. package/dist/cli/help.d.ts.map +1 -0
  43. package/dist/cli/index.d.ts +15 -0
  44. package/dist/cli/index.d.ts.map +1 -0
  45. package/{src/cli-module.ts → dist/cli-module.d.ts} +2 -8
  46. package/dist/cli-module.d.ts.map +1 -0
  47. package/dist/cli-primitives/box.d.ts +11 -0
  48. package/dist/cli-primitives/box.d.ts.map +1 -0
  49. package/dist/cli-primitives/cli-table.d.ts +11 -0
  50. package/dist/cli-primitives/cli-table.d.ts.map +1 -0
  51. package/dist/cli-primitives/divider.d.ts +11 -0
  52. package/dist/cli-primitives/divider.d.ts.map +1 -0
  53. package/dist/cli-primitives/header.d.ts +12 -0
  54. package/dist/cli-primitives/header.d.ts.map +1 -0
  55. package/{src/cli-primitives/index.ts → dist/cli-primitives/index.d.ts} +1 -1
  56. package/dist/cli-primitives/index.d.ts.map +1 -0
  57. package/dist/cli-primitives/server-fallback.d.ts +25 -0
  58. package/dist/cli-primitives/server-fallback.d.ts.map +1 -0
  59. package/dist/cli-primitives/spinner.d.ts +47 -0
  60. package/dist/cli-primitives/spinner.d.ts.map +1 -0
  61. package/dist/cli-primitives/step.d.ts +11 -0
  62. package/dist/cli-primitives/step.d.ts.map +1 -0
  63. package/dist/cli.cjs +2 -0
  64. package/dist/cli.cjs.map +1 -0
  65. package/dist/cli.js +12 -0
  66. package/dist/cli.js.map +1 -0
  67. package/dist/constants.d.ts +235 -0
  68. package/dist/constants.d.ts.map +1 -0
  69. package/dist/core.cjs +2 -0
  70. package/dist/core.cjs.map +1 -0
  71. package/dist/core.d.ts +127 -0
  72. package/dist/core.d.ts.map +1 -0
  73. package/dist/core.js +291 -0
  74. package/dist/core.js.map +1 -0
  75. package/dist/example.d.ts +18 -0
  76. package/dist/example.d.ts.map +1 -0
  77. package/dist/exports-module.d.ts +196 -0
  78. package/dist/exports-module.d.ts.map +1 -0
  79. package/dist/exports.cjs +2 -0
  80. package/dist/exports.cjs.map +1 -0
  81. package/dist/exports.js +238 -0
  82. package/dist/exports.js.map +1 -0
  83. package/dist/handlers/AnalyticsLogHandler.d.ts +8 -0
  84. package/dist/handlers/AnalyticsLogHandler.d.ts.map +1 -0
  85. package/dist/handlers/ExportLogHandler.d.ts +100 -0
  86. package/dist/handlers/ExportLogHandler.d.ts.map +1 -0
  87. package/dist/handlers/FileLogHandler.d.ts +33 -0
  88. package/dist/handlers/FileLogHandler.d.ts.map +1 -0
  89. package/dist/handlers/RemoteLogHandler.d.ts +11 -0
  90. package/dist/handlers/RemoteLogHandler.d.ts.map +1 -0
  91. package/{src/handlers/index.ts → dist/handlers/index.d.ts} +2 -2
  92. package/dist/handlers/index.d.ts.map +1 -0
  93. package/dist/hooks/HookManager.d.ts +21 -0
  94. package/dist/hooks/HookManager.d.ts.map +1 -0
  95. package/{src/hooks/index.ts → dist/hooks/index.d.ts} +1 -0
  96. package/dist/hooks/index.d.ts.map +1 -0
  97. package/dist/index.cjs +2 -0
  98. package/dist/index.cjs.map +1 -0
  99. package/dist/index.d.ts +161 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +627 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/main.d.ts +2 -0
  104. package/dist/main.d.ts.map +1 -0
  105. package/dist/serializers/SerializerRegistry.d.ts +16 -0
  106. package/dist/serializers/SerializerRegistry.d.ts.map +1 -0
  107. package/{src/serializers/index.ts → dist/serializers/index.d.ts} +1 -0
  108. package/dist/serializers/index.d.ts.map +1 -0
  109. package/dist/styling/LogStyleBuilder.d.ts +146 -0
  110. package/dist/styling/LogStyleBuilder.d.ts.map +1 -0
  111. package/dist/styling/SemanticStyles.d.ts +178 -0
  112. package/dist/styling/SemanticStyles.d.ts.map +1 -0
  113. package/dist/styling/SmartPresets.d.ts +22 -0
  114. package/dist/styling/SmartPresets.d.ts.map +1 -0
  115. package/dist/styling/StyleBuilder.d.ts +140 -0
  116. package/dist/styling/StyleBuilder.d.ts.map +1 -0
  117. package/dist/styling/StyleCache.d.ts +42 -0
  118. package/dist/styling/StyleCache.d.ts.map +1 -0
  119. package/dist/styling/banners.d.ts +42 -0
  120. package/dist/styling/banners.d.ts.map +1 -0
  121. package/dist/styling/index.d.ts +10 -0
  122. package/dist/styling/index.d.ts.map +1 -0
  123. package/dist/styling/themes.d.ts +7 -0
  124. package/dist/styling/themes.d.ts.map +1 -0
  125. package/dist/styling-module.d.ts +178 -0
  126. package/dist/styling-module.d.ts.map +1 -0
  127. package/dist/styling.cjs +2 -0
  128. package/dist/styling.cjs.map +1 -0
  129. package/dist/styling.js +146 -0
  130. package/dist/styling.js.map +1 -0
  131. package/dist/terminal/color-converter.d.ts +73 -0
  132. package/dist/terminal/color-converter.d.ts.map +1 -0
  133. package/dist/terminal/formatter.d.ts +20 -0
  134. package/dist/terminal/formatter.d.ts.map +1 -0
  135. package/dist/terminal/terminal-renderer.d.ts +77 -0
  136. package/dist/terminal/terminal-renderer.d.ts.map +1 -0
  137. package/dist/transports/ConsoleTransport.d.ts +9 -0
  138. package/dist/transports/ConsoleTransport.d.ts.map +1 -0
  139. package/dist/transports/FileTransport.d.ts +15 -0
  140. package/dist/transports/FileTransport.d.ts.map +1 -0
  141. package/dist/transports/HttpTransport.d.ts +16 -0
  142. package/dist/transports/HttpTransport.d.ts.map +1 -0
  143. package/dist/transports/TransportManager.d.ts +14 -0
  144. package/dist/transports/TransportManager.d.ts.map +1 -0
  145. package/{src/transports/index.ts → dist/transports/index.d.ts} +1 -0
  146. package/dist/transports/index.d.ts.map +1 -0
  147. package/{src/types/core.ts → dist/types/core.d.ts} +25 -62
  148. package/dist/types/core.d.ts.map +1 -0
  149. package/{src/types/handlers.ts → dist/types/handlers.d.ts} +5 -15
  150. package/dist/types/handlers.d.ts.map +1 -0
  151. package/{src/types/hooks.ts → dist/types/hooks.d.ts} +3 -12
  152. package/dist/types/hooks.d.ts.map +1 -0
  153. package/dist/types/index.d.ts +11 -0
  154. package/dist/types/index.d.ts.map +1 -0
  155. package/{src/types/serializers.ts → dist/types/serializers.d.ts} +1 -6
  156. package/dist/types/serializers.d.ts.map +1 -0
  157. package/{src/types/transports.ts → dist/types/transports.d.ts} +2 -7
  158. package/dist/types/transports.d.ts.map +1 -0
  159. package/dist/utils/adapter.d.ts +48 -0
  160. package/dist/utils/adapter.d.ts.map +1 -0
  161. package/dist/utils/ansi-colors.d.ts +156 -0
  162. package/dist/utils/ansi-colors.d.ts.map +1 -0
  163. package/dist/utils/environment-detector.d.ts +45 -0
  164. package/dist/utils/environment-detector.d.ts.map +1 -0
  165. package/dist/utils/environment.d.ts +47 -0
  166. package/dist/utils/environment.d.ts.map +1 -0
  167. package/dist/utils/formatting.d.ts +58 -0
  168. package/dist/utils/formatting.d.ts.map +1 -0
  169. package/dist/utils/index.d.ts +8 -0
  170. package/dist/utils/index.d.ts.map +1 -0
  171. package/dist/utils/opentui-detection.d.ts +34 -0
  172. package/dist/utils/opentui-detection.d.ts.map +1 -0
  173. package/dist/utils/output.d.ts +46 -0
  174. package/dist/utils/output.d.ts.map +1 -0
  175. package/dist/utils/stackTrace.d.ts +6 -0
  176. package/dist/utils/stackTrace.d.ts.map +1 -0
  177. package/dist/utils/timestamps.d.ts +20 -0
  178. package/dist/utils/timestamps.d.ts.map +1 -0
  179. package/{src/writers/BufferWriter.ts → dist/writers/BufferWriter.d.ts} +16 -77
  180. package/dist/writers/BufferWriter.d.ts.map +1 -0
  181. package/{src/writers/index.ts → dist/writers/index.d.ts} +1 -1
  182. package/dist/writers/index.d.ts.map +1 -0
  183. package/package.json +5 -1
  184. package/.claude/settings.local.json +0 -48
  185. package/.github/workflows/ci-quality.yml +0 -357
  186. package/.github/workflows/docs-demo.yml +0 -119
  187. package/.github/workflows/releases-core.yml +0 -512
  188. package/.github/workflows/releases-full.yml +0 -582
  189. package/.github/workflows-backup/ci.yml +0 -221
  190. package/.github/workflows-backup/nightly.yml +0 -196
  191. package/.github/workflows-backup/release-optimized.yml +0 -373
  192. package/.github/workflows-backup/release.yml +0 -269
  193. package/.release-notes-0.2.0.md +0 -129
  194. package/.yamllint +0 -28
  195. package/CHANGELOG.json +0 -1120
  196. package/CHANGELOG.md +0 -209
  197. package/CLAUDE.md +0 -217
  198. package/demo.html +0 -847
  199. package/docs/API.md +0 -918
  200. package/docs/CORE.md +0 -264
  201. package/docs/DEVELOPMENT.md +0 -731
  202. package/docs/EXPORTS.md +0 -467
  203. package/docs/PACKAGES.md +0 -244
  204. package/docs/STYLING.md +0 -405
  205. package/docs/_config.yml +0 -36
  206. package/docs/index.md +0 -179
  207. package/examples/README.md +0 -208
  208. package/examples/basic-logging.js +0 -75
  209. package/examples/data-export.js +0 -234
  210. package/examples/package.json +0 -16
  211. package/examples/performance-timing.js +0 -170
  212. package/examples/simplified-api.js +0 -124
  213. package/examples/styling-themes.js +0 -207
  214. package/index.html +0 -358
  215. package/packages/core/package.json +0 -57
  216. package/packages/exports/package.json +0 -41
  217. package/packages/nodejs-opentui/README.md +0 -232
  218. package/packages/nodejs-opentui/package.json +0 -72
  219. package/packages/nodejs-opentui/src/LogRenderer.ts +0 -171
  220. package/packages/nodejs-opentui/src/OpenTUILogHandler.ts +0 -178
  221. package/packages/nodejs-opentui/src/components/LogBadge.tsx +0 -131
  222. package/packages/nodejs-opentui/src/index.ts +0 -133
  223. package/packages/nodejs-opentui/src/types.ts +0 -158
  224. package/packages/nodejs-opentui/tsconfig.json +0 -20
  225. package/packages/styling/package.json +0 -41
  226. package/playground/demo-all.ts +0 -95
  227. package/playground/demo-box.ts +0 -85
  228. package/playground/demo-levels.ts +0 -56
  229. package/playground/demo-real-world.ts +0 -98
  230. package/playground/demo-spinner.ts +0 -77
  231. package/playground/demo-steps.ts +0 -72
  232. package/playground/demo-table.ts +0 -83
  233. package/project-utils/README.md +0 -172
  234. package/project-utils/auto-release-gemini.ts +0 -1193
  235. package/project-utils/auto-release-ui.ts +0 -1329
  236. package/project-utils/commit-generator.ts +0 -1385
  237. package/project-utils/commit-ui.ts +0 -264
  238. package/project-utils/git-utils.ts +0 -199
  239. package/project-utils/github-release-manager.ts +0 -466
  240. package/project-utils/project-config.ts +0 -260
  241. package/project-utils/prompt-templates.js +0 -345
  242. package/project-utils/prompt-templates.ts +0 -422
  243. package/project-utils/version-manager.ts +0 -1078
  244. package/src/Logger.ts +0 -1858
  245. package/src/ScopedLogger.ts +0 -256
  246. package/src/cli/CommandProcessor.ts +0 -248
  247. package/src/cli/commands/ConfigCommand.ts +0 -93
  248. package/src/cli/commands/ExportCommand.ts +0 -276
  249. package/src/cli/commands/HistoryCommand.ts +0 -117
  250. package/src/cli/commands/StatusCommand.ts +0 -112
  251. package/src/cli/commands/ThemeCommand.ts +0 -88
  252. package/src/cli/help.ts +0 -127
  253. package/src/cli/index.ts +0 -71
  254. package/src/cli-primitives/box.ts +0 -86
  255. package/src/cli-primitives/cli-table.ts +0 -62
  256. package/src/cli-primitives/divider.ts +0 -17
  257. package/src/cli-primitives/header.ts +0 -18
  258. package/src/cli-primitives/server-fallback.ts +0 -54
  259. package/src/cli-primitives/spinner.ts +0 -133
  260. package/src/cli-primitives/step.ts +0 -22
  261. package/src/constants.ts +0 -313
  262. package/src/core.ts +0 -397
  263. package/src/example.ts +0 -210
  264. package/src/exports-module.ts +0 -311
  265. package/src/handlers/AnalyticsLogHandler.ts +0 -22
  266. package/src/handlers/ExportLogHandler.ts +0 -610
  267. package/src/handlers/FileLogHandler.ts +0 -169
  268. package/src/handlers/RemoteLogHandler.ts +0 -42
  269. package/src/hooks/HookManager.ts +0 -177
  270. package/src/index.ts +0 -395
  271. package/src/main.ts +0 -196
  272. package/src/serializers/SerializerRegistry.ts +0 -173
  273. package/src/style.css +0 -96
  274. package/src/styling/LogStyleBuilder.ts +0 -355
  275. package/src/styling/SemanticStyles.ts +0 -380
  276. package/src/styling/SmartPresets.ts +0 -288
  277. package/src/styling/StyleBuilder.ts +0 -319
  278. package/src/styling/StyleCache.ts +0 -131
  279. package/src/styling/banners.ts +0 -168
  280. package/src/styling/index.ts +0 -27
  281. package/src/styling/themes.ts +0 -235
  282. package/src/styling-module.ts +0 -244
  283. package/src/terminal/color-converter.ts +0 -315
  284. package/src/terminal/formatter.ts +0 -242
  285. package/src/terminal/terminal-renderer.ts +0 -342
  286. package/src/transports/ConsoleTransport.ts +0 -28
  287. package/src/transports/FileTransport.ts +0 -53
  288. package/src/transports/HttpTransport.ts +0 -56
  289. package/src/transports/TransportManager.ts +0 -130
  290. package/src/types/index.ts +0 -83
  291. package/src/typescript.svg +0 -1
  292. package/src/utils/adapter.ts +0 -291
  293. package/src/utils/ansi-colors.ts +0 -333
  294. package/src/utils/environment-detector.ts +0 -170
  295. package/src/utils/environment.ts +0 -94
  296. package/src/utils/formatting.ts +0 -332
  297. package/src/utils/index.ts +0 -33
  298. package/src/utils/opentui-detection.ts +0 -138
  299. package/src/utils/output.ts +0 -227
  300. package/src/utils/stackTrace.ts +0 -144
  301. package/src/utils/timestamps.ts +0 -80
  302. package/src/vite-env.d.ts +0 -1
  303. package/test-core-browser.html +0 -237
  304. package/test-core-node.js +0 -63
  305. package/tests/test-conflict-resolution.ts +0 -391
  306. package/tests/validate-workflows.sh +0 -131
  307. package/tests/yaml-autofix.sh +0 -146
  308. package/tsconfig.json +0 -50
  309. package/vite.config.ts +0 -256
  310. /package/{public → dist}/vite.svg +0 -0
@@ -1,1078 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Version Manager para Better Logger
5
- * Analiza commits, extrae changelog, asigna versiones y actualiza archivos
6
- */
7
-
8
- import { readFileSync, writeFileSync, existsSync } from 'fs';
9
- import { join } from 'path';
10
-
11
- interface ChangelogEntry {
12
- type: 'feature' | 'fix' | 'improvement' | 'breaking';
13
- title: string;
14
- description: string;
15
- }
16
-
17
- interface Version {
18
- version: string;
19
- date: string;
20
- type: 'initial' | 'major' | 'minor' | 'patch';
21
- title: string;
22
- changes: ChangelogEntry[];
23
- technical_notes: string;
24
- breaking_changes: string[];
25
- commit_hash: string;
26
- prefix?: string; // pre-alpha, alpha, beta, rc, o undefined para stable
27
- affected_modules?: string[]; // Módulos afectados en esta versión
28
- module_versions?: Record<string, string>; // Versiones específicas de cada módulo
29
- }
30
-
31
- interface ChangelogData {
32
- current_version: string;
33
- versions: Version[];
34
- }
35
-
36
- interface CommitInfo {
37
- hash: string;
38
- date: string;
39
- title: string;
40
- description: string;
41
- technical_section?: string;
42
- changelog_section?: string;
43
- }
44
-
45
- class VersionManager {
46
- private projectRoot: string;
47
- private changelogPath: string;
48
- private packageJsonPath: string;
49
- private modulePackagePaths: Record<string, string>;
50
-
51
- constructor() {
52
- this.projectRoot = process.cwd();
53
- this.changelogPath = join(this.projectRoot, 'CHANGELOG.json');
54
- this.packageJsonPath = join(this.projectRoot, 'package.json');
55
- this.modulePackagePaths = {
56
- 'core': join(this.projectRoot, 'packages/core/package.json'),
57
- 'styling': join(this.projectRoot, 'packages/styling/package.json'),
58
- 'exports': join(this.projectRoot, 'packages/exports/package.json')
59
- };
60
- }
61
-
62
- /**
63
- * Ejecuta comando git y devuelve resultado
64
- */
65
- private async gitCommand(args: string[]): Promise<string> {
66
- const { spawn } = await import('child_process');
67
-
68
- return new Promise((resolve, reject) => {
69
- const proc = spawn('git', args, {
70
- cwd: this.projectRoot,
71
- stdio: ['pipe', 'pipe', 'pipe']
72
- });
73
-
74
- let stdout = '';
75
- let stderr = '';
76
-
77
- proc.stdout?.on('data', (data) => {
78
- stdout += data.toString();
79
- });
80
-
81
- proc.stderr?.on('data', (data) => {
82
- stderr += data.toString();
83
- });
84
-
85
- proc.on('exit', (code) => {
86
- if (code !== 0) {
87
- reject(new Error(`Git error: ${stderr || 'Git command failed'}`));
88
- } else {
89
- resolve(stdout.trim());
90
- }
91
- });
92
-
93
- proc.on('error', (error) => {
94
- reject(error);
95
- });
96
- });
97
- }
98
-
99
- /**
100
- * Obtiene todos los commits desde un hash específico
101
- */
102
- private async getCommitsSince(sinceHash?: string): Promise<CommitInfo[]> {
103
- const args = ['log', '--pretty=format:%H|%ci|%s', '--reverse'];
104
- if (sinceHash) {
105
- args.push(`${sinceHash}..HEAD`);
106
- }
107
-
108
- const output = await this.gitCommand(args);
109
- if (!output) return [];
110
-
111
- const commits: CommitInfo[] = [];
112
-
113
- for (const line of output.split('\n')) {
114
- const [hash, date, title] = line.split('|');
115
- if (!hash) continue;
116
-
117
- // Obtener el mensaje completo del commit
118
- try {
119
- const fullMessage = await this.gitCommand(['log', '-1', '--pretty=format:%B', hash]);
120
- const sections = this.parseCommitMessage(fullMessage);
121
-
122
- commits.push({
123
- hash,
124
- date: new Date(date).toISOString().split('T')[0],
125
- title,
126
- description: fullMessage,
127
- technical_section: sections.technical,
128
- changelog_section: sections.changelog
129
- });
130
- } catch (error) {
131
- console.warn(`⚠️ No se pudo obtener mensaje completo para commit ${hash}: ${error}`);
132
- commits.push({
133
- hash,
134
- date: new Date(date).toISOString().split('T')[0],
135
- title,
136
- description: title
137
- });
138
- }
139
- }
140
-
141
- return commits;
142
- }
143
-
144
- /**
145
- * Extrae secciones <technical> y <changelog> de un mensaje de commit
146
- */
147
- private parseCommitMessage(message: string): { technical?: string; changelog?: string } {
148
- const technicalMatch = message.match(/<technical>([\s\S]*?)<\/technical>/);
149
- const changelogMatch = message.match(/<changelog>([\s\S]*?)<\/changelog>/);
150
-
151
- return {
152
- technical: technicalMatch?.[1]?.trim(),
153
- changelog: changelogMatch?.[1]?.trim()
154
- };
155
- }
156
-
157
- /**
158
- * Convierte sección de changelog en entradas estructuradas
159
- */
160
- private parseChangelogSection(changelog: string): ChangelogEntry[] {
161
- if (!changelog) return [];
162
-
163
- const entries: ChangelogEntry[] = [];
164
- const lines = changelog.split('\n').map(line => line.trim()).filter(line => line);
165
-
166
- let currentSection = '';
167
- let currentEntries: string[] = [];
168
-
169
- for (const line of lines) {
170
- if (line.startsWith('##')) {
171
- // Procesar sección anterior
172
- if (currentSection && currentEntries.length > 0) {
173
- entries.push(...this.processSectionEntries(currentSection, currentEntries));
174
- }
175
-
176
- // Nueva sección
177
- currentSection = line.replace(/^##\s*/, '').toLowerCase();
178
- currentEntries = [];
179
- } else if (line.startsWith('-')) {
180
- currentEntries.push(line.replace(/^-\s*/, ''));
181
- }
182
- }
183
-
184
- // Procesar última sección
185
- if (currentSection && currentEntries.length > 0) {
186
- entries.push(...this.processSectionEntries(currentSection, currentEntries));
187
- }
188
-
189
- return entries;
190
- }
191
-
192
- /**
193
- * Procesa entradas de una sección específica del changelog
194
- */
195
- private processSectionEntries(section: string, entries: string[]): ChangelogEntry[] {
196
- let type: ChangelogEntry['type'] = 'improvement';
197
-
198
- if (section.includes('fix') || section.includes('🐛')) {
199
- type = 'fix';
200
- } else if (section.includes('feature') || section.includes('✨')) {
201
- type = 'feature';
202
- } else if (section.includes('breaking')) {
203
- type = 'breaking';
204
- }
205
-
206
- return entries.map(entry => ({
207
- type,
208
- title: entry.split('.')[0] || entry,
209
- description: entry
210
- }));
211
- }
212
-
213
- /**
214
- * Determina el tipo de versión basado en los cambios
215
- */
216
- private determineVersionType(commits: CommitInfo[]): Version['type'] {
217
- const hasBreaking = commits.some(c =>
218
- c.changelog_section?.includes('breaking') ||
219
- c.title.toLowerCase().includes('breaking')
220
- );
221
-
222
- if (hasBreaking) return 'major';
223
-
224
- const hasFeature = commits.some(c =>
225
- c.title.startsWith('feat(') ||
226
- c.changelog_section?.includes('✨') ||
227
- c.changelog_section?.toLowerCase().includes('feature')
228
- );
229
-
230
- if (hasFeature) return 'minor';
231
-
232
- return 'patch';
233
- }
234
-
235
- /**
236
- * Incrementa versión según el tipo, considerando prefijos
237
- */
238
- private incrementVersion(
239
- currentVersion: string,
240
- type: Version['type'],
241
- targetPrefix?: string,
242
- overrideType?: Version['type']
243
- ): string {
244
- // Extraer prefix y versión base
245
- const { prefix, baseVersion } = this.parseVersionString(currentVersion);
246
- const [major, minor, patch] = baseVersion.split('.').map(Number);
247
-
248
- // Si se especifica un targetPrefix, usarlo; si no, mantener el actual
249
- const newPrefix = targetPrefix !== undefined ? targetPrefix : prefix;
250
-
251
- // Si se especifica un override del tipo, usarlo
252
- const actualType = overrideType || type;
253
-
254
- let newBaseVersion: string;
255
- switch (actualType) {
256
- case 'major':
257
- newBaseVersion = `${major + 1}.0.0`;
258
- break;
259
- case 'minor':
260
- newBaseVersion = `${major}.${minor + 1}.0`;
261
- break;
262
- case 'patch':
263
- newBaseVersion = `${major}.${minor}.${patch + 1}`;
264
- break;
265
- default:
266
- newBaseVersion = baseVersion;
267
- }
268
-
269
- // Determinar incremento de prerelease
270
- const prereleaseIncrement = this.calculatePrereleaseIncrement(
271
- currentVersion,
272
- newPrefix,
273
- newBaseVersion,
274
- actualType
275
- );
276
-
277
- return this.buildVersionString(newPrefix, newBaseVersion, prereleaseIncrement);
278
- }
279
-
280
- /**
281
- * Calcula el incremento de prerelease apropiado
282
- */
283
- private calculatePrereleaseIncrement(
284
- currentVersion: string,
285
- targetPrefix?: string,
286
- newBaseVersion?: string,
287
- versionType?: Version['type']
288
- ): number {
289
- const { prefix: currentPrefix, baseVersion: currentBaseVersion, prereleaseIncrement } = this.parseVersionString(currentVersion);
290
-
291
- // Si cambiamos de prefijo o de versión base, resetear a 1
292
- if (targetPrefix !== currentPrefix || newBaseVersion !== currentBaseVersion) {
293
- return 1;
294
- }
295
-
296
- // Si mantenemos el mismo prefijo y versión base, incrementar
297
- return (prereleaseIncrement || 0) + 1;
298
- }
299
-
300
- /**
301
- * Parsea una versión con posible prefijo (soporta formatos legacy y semver)
302
- */
303
- private parseVersionString(version: string): { prefix?: string; baseVersion: string; prereleaseIncrement?: number } {
304
- // Formato semver: X.Y.Z-prefix.N (ej: 0.6.0-alpha.1)
305
- const semverMatch = version.match(/^(\d+\.\d+\.\d+)-(pre-alpha|alpha|beta|rc)\.(\d+)$/);
306
- if (semverMatch) {
307
- return {
308
- baseVersion: semverMatch[1],
309
- prefix: semverMatch[2],
310
- prereleaseIncrement: parseInt(semverMatch[3])
311
- };
312
- }
313
-
314
- // Formato legacy: prefix-X.Y.Z (ej: alpha-0.6.0) - para compatibilidad temporal
315
- const legacyMatch = version.match(/^(pre-alpha-|alpha-|beta-|rc-)?(.+)$/);
316
- if (legacyMatch) {
317
- return {
318
- prefix: legacyMatch[1]?.replace(/-$/, ''), // Remover el guión final
319
- baseVersion: legacyMatch[2],
320
- prereleaseIncrement: 1 // Default para conversión
321
- };
322
- }
323
-
324
- return { baseVersion: version };
325
- }
326
-
327
- /**
328
- * Construye una versión con prefijo en formato semver compatible con NPM
329
- */
330
- private buildVersionString(prefix?: string, baseVersion?: string, prereleaseIncrement?: number): string {
331
- if (!baseVersion) return '1.0.0';
332
- if (!prefix) return baseVersion; // Sin prefijo = estable
333
-
334
- // Formato semver: baseVersion-prefix.increment (ej: 0.6.0-alpha.1)
335
- const increment = prereleaseIncrement || 1;
336
- return `${baseVersion}-${prefix}.${increment}`;
337
- }
338
-
339
- /**
340
- * Valida que la transición de prefijo sea lógica
341
- */
342
- private validatePrefixTransition(currentVersion: string, targetPrefix?: string): void {
343
- const { prefix: currentPrefix } = this.parseVersionString(currentVersion);
344
-
345
- // Definir orden de prefijos (undefined = stable)
346
- const prefixOrder = ['pre-alpha', 'alpha', 'beta', 'rc', undefined];
347
- const currentIndex = prefixOrder.indexOf(currentPrefix);
348
- const targetIndex = prefixOrder.indexOf(targetPrefix);
349
-
350
- // Permitir cualquier transición, pero advertir sobre regresiones
351
- if (currentIndex !== -1 && targetIndex !== -1 && targetIndex < currentIndex) {
352
- console.warn(`⚠️ Advertencia: Transición de prefijo regresiva ${currentPrefix || 'stable'} → ${targetPrefix || 'stable'}`);
353
- console.warn(' Esto podría confundir a los usuarios sobre el estado de estabilidad.');
354
- }
355
-
356
- // Validar prefijos válidos
357
- const validPrefixes = ['pre-alpha', 'alpha', 'beta', 'rc'];
358
- if (targetPrefix && !validPrefixes.includes(targetPrefix)) {
359
- throw new Error(`❌ Prefijo inválido: ${targetPrefix}. Válidos: ${validPrefixes.join(', ')}, o sin prefijo para stable`);
360
- }
361
- }
362
-
363
- /**
364
- * Carga datos actuales del changelog
365
- */
366
- private loadChangelogData(): ChangelogData {
367
- if (existsSync(this.changelogPath)) {
368
- try {
369
- const content = readFileSync(this.changelogPath, 'utf-8');
370
- return JSON.parse(content);
371
- } catch (error) {
372
- console.warn('⚠️ Error leyendo changelog.json, creando nuevo');
373
- }
374
- }
375
-
376
- return {
377
- current_version: '0.1.0',
378
- versions: []
379
- };
380
- }
381
-
382
- /**
383
- * Obtiene el último commit versionado
384
- */
385
- private getLastVersionedCommit(data: ChangelogData): string | undefined {
386
- const sortedVersions = [...data.versions].sort((a, b) =>
387
- new Date(b.date).getTime() - new Date(a.date).getTime()
388
- );
389
-
390
- return sortedVersions[0]?.commit_hash;
391
- }
392
-
393
- /**
394
- * Analiza commits y genera nueva versión
395
- */
396
- async analyzeAndVersion(options: {
397
- type?: Version['type'];
398
- prefix?: string;
399
- } = {}): Promise<void> {
400
- console.log('🚀 Iniciando análisis de versionado...\n');
401
-
402
- try {
403
- // Cargar datos existentes
404
- const changelogData = this.loadChangelogData();
405
- console.log(`📋 Versión actual: ${changelogData.current_version}`);
406
-
407
- // Obtener último commit versionado
408
- const lastVersionedCommit = this.getLastVersionedCommit(changelogData);
409
- console.log(`🔍 Último commit versionado: ${lastVersionedCommit || 'ninguno'}`);
410
-
411
- // Obtener commits nuevos
412
- const newCommits = await this.getCommitsSince(lastVersionedCommit);
413
- console.log(`📝 Encontrados ${newCommits.length} commits nuevos`);
414
-
415
- if (newCommits.length === 0) {
416
- console.log('✅ No hay commits nuevos para versionar');
417
- return;
418
- }
419
-
420
- // Mostrar commits que se van a versionar
421
- console.log('\n📋 Commits que se incluirán en la nueva versión:');
422
- newCommits.forEach(commit => {
423
- console.log(` • ${commit.hash.slice(0, 7)} - ${commit.title}`);
424
- });
425
-
426
- // Determinar tipo de versión
427
- const detectedVersionType = this.determineVersionType(newCommits);
428
- const finalVersionType = options.type || detectedVersionType;
429
-
430
- // Si se especifica un prefix, validarlo
431
- if (options.prefix !== undefined) {
432
- this.validatePrefixTransition(changelogData.current_version, options.prefix);
433
- }
434
-
435
- const newVersion = this.incrementVersion(
436
- changelogData.current_version,
437
- detectedVersionType,
438
- options.prefix,
439
- finalVersionType
440
- );
441
-
442
- console.log(`\n🏷️ Nueva versión: ${changelogData.current_version} → ${newVersion}`);
443
- console.log(`📊 Tipo detectado: ${detectedVersionType}${options.type ? ` → Forzado: ${options.type}` : ''}`);
444
- if (options.prefix !== undefined) {
445
- const { prefix: currentPrefix } = this.parseVersionString(changelogData.current_version);
446
- console.log(`🏷️ Prefix: ${currentPrefix || 'stable'} → ${options.prefix || 'stable'}`);
447
- }
448
-
449
- // Procesar cambios
450
- const allChanges: ChangelogEntry[] = [];
451
- let technicalNotes = '';
452
-
453
- for (const commit of newCommits) {
454
- if (commit.changelog_section) {
455
- const changes = this.parseChangelogSection(commit.changelog_section);
456
- allChanges.push(...changes);
457
- } else {
458
- // Generar entrada básica desde el título del commit
459
- let type: ChangelogEntry['type'] = 'improvement';
460
- if (commit.title.startsWith('feat(')) type = 'feature';
461
- else if (commit.title.startsWith('fix(')) type = 'fix';
462
-
463
- allChanges.push({
464
- type,
465
- title: commit.title.replace(/^(feat|fix|refactor)\([^)]+\)\s*-\s*/, ''),
466
- description: commit.title
467
- });
468
- }
469
-
470
- if (commit.technical_section) {
471
- technicalNotes += `\n${commit.technical_section}`;
472
- }
473
- }
474
-
475
- // Crear nueva versión
476
- const { prefix } = this.parseVersionString(newVersion);
477
- const newVersionEntry: Version = {
478
- version: newVersion,
479
- date: new Date().toISOString().split('T')[0],
480
- type: finalVersionType,
481
- title: this.generateVersionTitle(allChanges, finalVersionType, prefix),
482
- changes: allChanges,
483
- technical_notes: technicalNotes.trim(),
484
- breaking_changes: allChanges
485
- .filter(c => c.type === 'breaking')
486
- .map(c => c.description),
487
- commit_hash: newCommits[newCommits.length - 1].hash,
488
- prefix
489
- };
490
-
491
- // Actualizar datos
492
- changelogData.current_version = newVersion;
493
- changelogData.versions.unshift(newVersionEntry); // Agregar al principio
494
-
495
- // Guardar changelog actualizado
496
- writeFileSync(this.changelogPath, JSON.stringify(changelogData, null, 2));
497
- console.log(`💾 Changelog actualizado: ${this.changelogPath}`);
498
-
499
- // Detectar módulos afectados y actualizar archivos de configuración
500
- const affectedModules = await this.detectAffectedModules();
501
- await this.updateAllVersionFiles(newVersion, affectedModules);
502
-
503
- console.log(`\n✅ Versionado completado exitosamente!`);
504
- console.log(`📦 Nueva versión: ${newVersion}`);
505
- console.log(`📋 Cambios incluidos: ${allChanges.length}`);
506
- console.log(`📝 Commits procesados: ${newCommits.length}`);
507
-
508
- // Sugerir creación de release si hay archivos de distribución disponibles
509
- const distDir = join(this.projectRoot, 'dist');
510
- if (existsSync(distDir)) {
511
- console.log(`\n💡 Archivos de distribución detectados en ${distDir}`);
512
- console.log(`🚀 Para crear release en GitHub ejecuta:`);
513
- console.log(` npm run release:github`);
514
- }
515
-
516
- } catch (error) {
517
- console.error('❌ Error durante el versionado:', error);
518
- throw error;
519
- }
520
- }
521
-
522
- /**
523
- * Genera título descriptivo para la versión
524
- */
525
- private generateVersionTitle(changes: ChangelogEntry[], type: Version['type'], prefix?: string): string {
526
- const features = changes.filter(c => c.type === 'feature');
527
- const fixes = changes.filter(c => c.type === 'fix');
528
- const improvements = changes.filter(c => c.type === 'improvement');
529
-
530
- // Prefijo para el título
531
- const prefixLabel = prefix ?
532
- `Versión ${prefix.charAt(0).toUpperCase() + prefix.slice(1)} - ` : '';
533
-
534
- if (type === 'major') {
535
- return `${prefixLabel}Actualización mayor con cambios significativos`;
536
- }
537
-
538
- if (features.length > 0) {
539
- const mainFeature = features[0].title;
540
- if (features.length === 1) {
541
- return `${prefixLabel}Nueva funcionalidad: ${mainFeature}`;
542
- }
543
- return `${prefixLabel}Nuevas funcionalidades incluyendo ${mainFeature} y ${features.length - 1} más`;
544
- }
545
-
546
- if (fixes.length > 0) {
547
- if (fixes.length === 1) {
548
- return `${prefixLabel}Corrección: ${fixes[0].title}`;
549
- }
550
- return `${prefixLabel}Correcciones y mejoras (${fixes.length} fixes, ${improvements.length} mejoras)`;
551
- }
552
-
553
- return `${prefixLabel}Mejoras y optimizaciones`;
554
- }
555
-
556
- /**
557
- * Actualiza versión en todos los archivos de configuración
558
- */
559
- private async updateAllVersionFiles(version: string, affectedModules?: string[]): Promise<void> {
560
- console.log(`🔄 Sincronizando versión ${version} en todos los archivos...`);
561
-
562
- // Actualizar package.json principal y modulares
563
- await this.updatePackageVersion(version, affectedModules);
564
-
565
- // No hay archivos adicionales que actualizar para Better Logger
566
-
567
- // Better Logger no requiere sincronización OTA
568
-
569
- console.log(`✅ Todas las versiones sincronizadas en ${version}`);
570
- }
571
-
572
- /**
573
- * Detecta qué módulos han sido afectados basado en archivos cambiados
574
- */
575
- private async detectAffectedModules(): Promise<string[]> {
576
- try {
577
- const changedFiles = await this.gitCommand(['diff', '--name-only', 'HEAD~1']);
578
- const affectedModules = new Set<string>();
579
-
580
- for (const file of changedFiles.split('\n').filter(f => f.trim())) {
581
- // Detectar por patterns de archivos
582
- if (file.includes('core') || file.includes('Logger.ts') || file.includes('constants.ts')) {
583
- affectedModules.add('core');
584
- }
585
- if (file.includes('styling') || file.includes('Style')) {
586
- affectedModules.add('styling');
587
- }
588
- if (file.includes('exports') || file.includes('Handler')) {
589
- affectedModules.add('exports');
590
- }
591
- }
592
-
593
- // Si no se puede determinar, afectar todos los módulos
594
- const result = Array.from(affectedModules);
595
- if (result.length === 0) {
596
- console.log(`⚠️ No se pudo determinar módulos afectados, usando todos`);
597
- return ['core', 'styling', 'exports'];
598
- }
599
-
600
- console.log(`📋 Módulos afectados detectados: ${result.join(', ')}`);
601
- return result;
602
- } catch (error) {
603
- console.warn(`⚠️ Error detectando módulos afectados:`, error);
604
- return ['core', 'styling', 'exports']; // fallback
605
- }
606
- }
607
-
608
- /**
609
- * Actualiza versión en package.json principal y modulares
610
- */
611
- private async updatePackageVersion(version: string, modules?: string[]): Promise<void> {
612
- // Actualizar package.json principal
613
- const packageJson = JSON.parse(readFileSync(this.packageJsonPath, 'utf-8'));
614
- packageJson.version = version;
615
- writeFileSync(this.packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
616
- console.log(`📦 Actualizado package.json → ${version}`);
617
-
618
- // Actualizar package.json de módulos afectados
619
- if (modules && modules.length > 0) {
620
- for (const moduleName of modules) {
621
- const modulePath = this.modulePackagePaths[moduleName];
622
- if (modulePath && existsSync(modulePath)) {
623
- const modulePackageJson = JSON.parse(readFileSync(modulePath, 'utf-8'));
624
- modulePackageJson.version = version;
625
-
626
- // Actualizar peerDependencies si existen
627
- if (modulePackageJson.peerDependencies) {
628
- Object.keys(modulePackageJson.peerDependencies).forEach(dep => {
629
- if (dep.startsWith('@mks2508/better-logger')) {
630
- modulePackageJson.peerDependencies[dep] = `^${version}`;
631
- }
632
- });
633
- }
634
-
635
- writeFileSync(modulePath, JSON.stringify(modulePackageJson, null, 2) + '\n');
636
- console.log(`📦 Actualizado ${moduleName}/package.json → ${version}`);
637
- }
638
- }
639
- }
640
- }
641
-
642
- /**
643
- * Actualiza versión en tauri.conf.json
644
- * Tauri requiere versionado semántico estricto (sin prefijos)
645
- */
646
- private async updateTauriVersion(version: string): Promise<void> {
647
- const tauriConfig = JSON.parse(readFileSync(this.tauriConfigPath, 'utf-8'));
648
-
649
- // Extraer solo la versión base para Tauri (sin prefijos)
650
- const { baseVersion } = this.parseVersionString(version);
651
- tauriConfig.version = baseVersion;
652
-
653
- writeFileSync(this.tauriConfigPath, JSON.stringify(tauriConfig, null, 2) + '\n');
654
- console.log(`🦀 Actualizado tauri.conf.json → ${baseVersion} (sin prefijo para semver)`);
655
- }
656
-
657
- /**
658
- * Actualiza versión en Cargo.toml
659
- * Cargo también requiere versionado semántico estricto (sin prefijos)
660
- */
661
- private async updateCargoVersion(version: string): Promise<void> {
662
- const cargoContent = readFileSync(this.cargoTomlPath, 'utf-8');
663
-
664
- // Extraer solo la versión base para Cargo (sin prefijos)
665
- const { baseVersion } = this.parseVersionString(version);
666
- const updatedContent = cargoContent.replace(
667
- /^version\s*=\s*"[^"]*"/m,
668
- `version = "${baseVersion}"`
669
- );
670
-
671
- writeFileSync(this.cargoTomlPath, updatedContent);
672
- console.log(`🦀 Actualizado Cargo.toml → ${baseVersion} (sin prefijo para semver)`);
673
- }
674
-
675
- /**
676
- * Sincroniza la nueva versión con el sistema OTA
677
- * Actualiza versions.json y mapea prefijos a canales OTA
678
- */
679
- private async syncWithOTASystem(version: string): Promise<void> {
680
- const versionsPath = join(this.projectRoot, 'versions.json');
681
-
682
- try {
683
- // Extraer información de la versión
684
- const { prefix, baseVersion } = this.parseVersionString(version);
685
-
686
- // Mapear prefix a canal OTA
687
- let targetChannel = 'stable';
688
- if (prefix === 'alpha' || prefix === 'beta') {
689
- targetChannel = 'beta';
690
- } else if (prefix === 'pre-alpha' || prefix === 'rc') {
691
- targetChannel = 'dev';
692
- }
693
-
694
- if (!existsSync(versionsPath)) {
695
- console.log('⚠️ versions.json no existe, creando estructura inicial...');
696
- await this.createInitialVersionsFile(baseVersion, targetChannel);
697
- return;
698
- }
699
-
700
- // Leer versions.json actual
701
- const versionsData = JSON.parse(readFileSync(versionsPath, 'utf-8'));
702
- const currentDate = new Date().toISOString();
703
- const buildNumber = currentDate.replace(/[-:.TZ]/g, '').slice(0, 12);
704
-
705
- // Actualizar versiones principales
706
- versionsData.frontend.version = baseVersion;
707
- versionsData.frontend.build = buildNumber;
708
- versionsData.frontend.lastUpdated = currentDate;
709
-
710
- versionsData.backend.version = baseVersion;
711
- versionsData.backend.build = buildNumber;
712
- versionsData.backend.lastUpdated = currentDate;
713
-
714
- // Actualizar canal OTA correspondiente
715
- versionsData.updateChannels[targetChannel].frontend = version;
716
- versionsData.updateChannels[targetChannel].backend = version;
717
-
718
- // Agregar entrada de changelog OTA
719
- const changelogEntry = {
720
- version: baseVersion,
721
- date: new Date().toISOString().split('T')[0],
722
- changes: [`Actualización automática desde version-manager (${version})`]
723
- };
724
-
725
- // Agregar al inicio del changelog (más reciente primero)
726
- if (!versionsData.frontend.changelog.find((entry: any) => entry.version === baseVersion)) {
727
- versionsData.frontend.changelog.unshift(changelogEntry);
728
- versionsData.backend.changelog.unshift(changelogEntry);
729
- }
730
-
731
- // Actualizar matriz de compatibilidad
732
- const compatibilityEntry = versionsData.compatibility.matrix.find((entry: any) =>
733
- entry.backend === baseVersion
734
- );
735
-
736
- if (!compatibilityEntry) {
737
- versionsData.compatibility.matrix.unshift({
738
- backend: baseVersion,
739
- frontend: [baseVersion]
740
- });
741
- }
742
-
743
- // Guardar versions.json actualizado
744
- writeFileSync(versionsPath, JSON.stringify(versionsData, null, 2));
745
- console.log(`🔄 Sistema OTA sincronizado → ${baseVersion} (canal: ${targetChannel})`);
746
-
747
- } catch (error) {
748
- console.warn(`⚠️ Error sincronizando sistema OTA: ${error}`);
749
- console.warn('El versionado principal continuará sin sincronización OTA');
750
- }
751
- }
752
-
753
- /**
754
- * Crea archivo versions.json inicial cuando no existe
755
- */
756
- private async createInitialVersionsFile(version: string, channel: string): Promise<void> {
757
- const currentDate = new Date().toISOString();
758
- const buildNumber = currentDate.replace(/[-:.TZ]/g, '').slice(0, 12);
759
-
760
- const initialVersions = {
761
- frontend: {
762
- version,
763
- build: buildNumber,
764
- lastUpdated: currentDate,
765
- changelog: [{
766
- version,
767
- date: new Date().toISOString().split('T')[0],
768
- changes: ['Inicialización automática del sistema OTA']
769
- }]
770
- },
771
- backend: {
772
- version,
773
- build: buildNumber,
774
- lastUpdated: currentDate,
775
- minimumFrontend: version,
776
- changelog: [{
777
- version,
778
- date: new Date().toISOString().split('T')[0],
779
- changes: ['Inicialización automática del sistema OTA']
780
- }]
781
- },
782
- compatibility: {
783
- matrix: [{
784
- backend: version,
785
- frontend: [version]
786
- }]
787
- },
788
- updateChannels: {
789
- stable: { frontend: version, backend: version },
790
- beta: { frontend: version, backend: version },
791
- dev: { frontend: version, backend: version }
792
- }
793
- };
794
-
795
- const versionsPath = join(this.projectRoot, 'versions.json');
796
- writeFileSync(versionsPath, JSON.stringify(initialVersions, null, 2));
797
- console.log(`🆕 Archivo versions.json creado con versión inicial: ${version}`);
798
- }
799
-
800
- /**
801
- * Sincroniza todos los archivos de configuración con la versión actual del changelog
802
- */
803
- async syncVersionFiles(): Promise<void> {
804
- console.log('🔄 Sincronizando archivos de configuración con versión actual...\n');
805
-
806
- try {
807
- // Cargar datos del changelog
808
- const changelogData = this.loadChangelogData();
809
- const currentVersion = changelogData.current_version;
810
-
811
- console.log(`📋 Versión actual en changelog: ${currentVersion}`);
812
-
813
- // Actualizar todos los archivos de configuración
814
- await this.updateAllVersionFiles(currentVersion);
815
-
816
- console.log(`\n✅ Sincronización completada exitosamente!`);
817
- console.log(`📦 Todos los archivos actualizados a: ${currentVersion}`);
818
-
819
- } catch (error) {
820
- console.error('❌ Error durante la sincronización:', error);
821
- throw error;
822
- }
823
- }
824
-
825
- /**
826
- * Procesa todos los commits existentes (para inicialización)
827
- */
828
- async initializeFromHistory(): Promise<void> {
829
- console.log('🔄 Inicializando changelog desde historial completo...\n');
830
-
831
- try {
832
- // Obtener TODOS los commits
833
- const allCommits = await this.getCommitsSince();
834
- console.log(`📝 Encontrados ${allCommits.length} commits totales en el historial`);
835
-
836
- if (allCommits.length === 0) {
837
- console.log('✅ No hay commits para procesar');
838
- return;
839
- }
840
-
841
- // Agrupar commits por tipo y fecha para crear versiones lógicas
842
- const versionGroups = this.groupCommitsIntoVersions(allCommits);
843
- console.log(`📊 Agrupados en ${versionGroups.length} versiones lógicas`);
844
-
845
- const changelogData: ChangelogData = {
846
- current_version: '0.1.0',
847
- versions: []
848
- };
849
-
850
- // Procesar cada grupo como una versión
851
- for (let i = 0; i < versionGroups.length; i++) {
852
- const group = versionGroups[i];
853
- const versionNumber = this.generateVersionNumber(i, versionGroups.length);
854
-
855
- const allChanges: ChangelogEntry[] = [];
856
- let technicalNotes = '';
857
-
858
- for (const commit of group.commits) {
859
- if (commit.changelog_section) {
860
- const changes = this.parseChangelogSection(commit.changelog_section);
861
- allChanges.push(...changes);
862
- } else {
863
- let type: ChangelogEntry['type'] = 'improvement';
864
- if (commit.title.startsWith('feat(')) type = 'feature';
865
- else if (commit.title.startsWith('fix(')) type = 'fix';
866
-
867
- allChanges.push({
868
- type,
869
- title: commit.title.replace(/^(feat|fix|refactor)\([^)]+\)\s*-\s*/, ''),
870
- description: commit.title
871
- });
872
- }
873
-
874
- if (commit.technical_section) {
875
- technicalNotes += `\n${commit.technical_section}`;
876
- }
877
- }
878
-
879
- const version: Version = {
880
- version: versionNumber,
881
- date: group.date,
882
- type: group.type,
883
- title: group.title,
884
- changes: allChanges,
885
- technical_notes: technicalNotes.trim(),
886
- breaking_changes: allChanges
887
- .filter(c => c.type === 'breaking')
888
- .map(c => c.description),
889
- commit_hash: group.commits[group.commits.length - 1].hash
890
- };
891
-
892
- changelogData.versions.push(version);
893
- }
894
-
895
- // La versión más reciente es la actual
896
- if (changelogData.versions.length > 0) {
897
- changelogData.current_version = changelogData.versions[0].version;
898
- }
899
-
900
- // Guardar changelog
901
- writeFileSync(this.changelogPath, JSON.stringify(changelogData, null, 2));
902
- console.log(`💾 Changelog inicializado: ${this.changelogPath}`);
903
-
904
- // Actualizar archivos de configuración
905
- await this.updateAllVersionFiles(changelogData.current_version);
906
-
907
- console.log(`\n✅ Inicialización completada!`);
908
- console.log(`📦 Versión actual: ${changelogData.current_version}`);
909
- console.log(`📋 Versiones creadas: ${changelogData.versions.length}`);
910
-
911
- } catch (error) {
912
- console.error('❌ Error durante la inicialización:', error);
913
- throw error;
914
- }
915
- }
916
-
917
- /**
918
- * Agrupa commits en versiones lógicas
919
- */
920
- private groupCommitsIntoVersions(commits: CommitInfo[]): Array<{
921
- commits: CommitInfo[];
922
- date: string;
923
- type: Version['type'];
924
- title: string;
925
- }> {
926
- const groups: Array<{
927
- commits: CommitInfo[];
928
- date: string;
929
- type: Version['type'];
930
- title: string;
931
- }> = [];
932
-
933
- // Agrupar por fechas similares y tipos de commits
934
- let currentGroup: CommitInfo[] = [];
935
- let currentDate = '';
936
-
937
- for (let i = 0; i < commits.length; i++) {
938
- const commit = commits[i];
939
-
940
- // Si es primer commit o fecha muy diferente, crear nuevo grupo
941
- if (!currentDate || this.daysDifference(currentDate, commit.date) > 7 || currentGroup.length >= 10) {
942
- if (currentGroup.length > 0) {
943
- groups.push({
944
- commits: [...currentGroup],
945
- date: currentDate,
946
- type: this.determineVersionType(currentGroup),
947
- title: this.generateGroupTitle(currentGroup)
948
- });
949
- }
950
- currentGroup = [commit];
951
- currentDate = commit.date;
952
- } else {
953
- currentGroup.push(commit);
954
- }
955
- }
956
-
957
- // Agregar último grupo
958
- if (currentGroup.length > 0) {
959
- groups.push({
960
- commits: currentGroup,
961
- date: currentDate,
962
- type: this.determineVersionType(currentGroup),
963
- title: this.generateGroupTitle(currentGroup)
964
- });
965
- }
966
-
967
- return groups.reverse(); // Más recientes primero
968
- }
969
-
970
- /**
971
- * Calcula diferencia en días entre fechas
972
- */
973
- private daysDifference(date1: string, date2: string): number {
974
- const d1 = new Date(date1).getTime();
975
- const d2 = new Date(date2).getTime();
976
- return Math.abs((d2 - d1) / (1000 * 60 * 60 * 24));
977
- }
978
-
979
- /**
980
- * Genera título para un grupo de commits
981
- */
982
- private generateGroupTitle(commits: CommitInfo[]): string {
983
- const features = commits.filter(c => c.title.startsWith('feat('));
984
- const fixes = commits.filter(c => c.title.startsWith('fix('));
985
-
986
- if (features.length > 0) {
987
- return `Nuevas funcionalidades y mejoras`;
988
- }
989
- if (fixes.length > 0) {
990
- return `Correcciones y optimizaciones`;
991
- }
992
- return `Mejoras del sistema`;
993
- }
994
-
995
- /**
996
- * Genera número de versión para inicialización
997
- */
998
- private generateVersionNumber(index: number, total: number): string {
999
- if (total === 1) return '1.0.0';
1000
-
1001
- if (index === 0) return '1.0.0'; // Versión más reciente
1002
- if (index < 3) return `0.${9 - index}.0`; // Versiones recientes
1003
-
1004
- // Versiones más antiguas
1005
- const patchVersion = Math.max(1, total - index);
1006
- return `0.1.${patchVersion}`;
1007
- }
1008
- }
1009
-
1010
- // Ejecutar script
1011
- if (import.meta.main) {
1012
- const manager = new VersionManager();
1013
-
1014
- const args = process.argv.slice(2);
1015
- const isInit = args.includes('--init') || args.includes('-i');
1016
- const isSync = args.includes('--sync') || args.includes('-s');
1017
- const autoApprove = args.includes('--auto-approve');
1018
- const noSync = args.includes('--no-sync');
1019
- const quiet = args.includes('--quiet');
1020
-
1021
- // Parsear parámetros adicionales
1022
- const typeIndex = args.indexOf('--type');
1023
- const type = typeIndex > -1 && args[typeIndex + 1] ? args[typeIndex + 1] as Version['type'] : undefined;
1024
-
1025
- const prefixIndex = args.indexOf('--prefix');
1026
- const prefix = prefixIndex > -1 ? (args[prefixIndex + 1] || '') : undefined;
1027
-
1028
- // Validar tipo si se especifica
1029
- if (type && !['major', 'minor', 'patch'].includes(type)) {
1030
- console.error(`❌ Tipo de versión inválido: ${type}. Válidos: major, minor, patch`);
1031
- process.exit(1);
1032
- }
1033
-
1034
- // Mostrar ayuda
1035
- if (args.includes('--help') || args.includes('-h')) {
1036
- console.log(`
1037
- 🚀 Version Manager para Better Logger
1038
-
1039
- Uso:
1040
- node project-utils/version-manager.ts [opciones]
1041
-
1042
- Opciones:
1043
- --init, -i Inicializar desde historial completo
1044
- --sync, -s Sincronizar archivos de configuración
1045
- --auto-approve Ejecución automática sin confirmaciones
1046
- --no-sync No sincronizar archivos de configuración
1047
- --quiet Ejecución silenciosa (solo errores y resultados)
1048
- --type <tipo> Forzar tipo de versión (major|minor|patch)
1049
- --prefix <prefijo> Cambiar prefijo (pre-alpha|alpha|beta|rc|'' para stable)
1050
- --help, -h Mostrar esta ayuda
1051
-
1052
- Ejemplos:
1053
- node project-utils/version-manager.ts # Análisis automático
1054
- node project-utils/version-manager.ts --auto-approve # Ejecución silenciosa
1055
- node project-utils/version-manager.ts --type minor --auto-approve
1056
- node project-utils/version-manager.ts --prefix beta --auto-approve
1057
- node project-utils/version-manager.ts --sync --auto-approve
1058
- node project-utils/version-manager.ts --quiet --auto-approve # Para workflows
1059
- `);
1060
- process.exit(0);
1061
- }
1062
-
1063
- try {
1064
- if (isInit) {
1065
- await manager.initializeFromHistory();
1066
- } else if (isSync) {
1067
- await manager.syncVersionFiles();
1068
- } else {
1069
- await manager.analyzeAndVersion({
1070
- type,
1071
- prefix: prefix === '' ? undefined : prefix
1072
- });
1073
- }
1074
- } catch (error) {
1075
- console.error('❌ Error:', error);
1076
- process.exit(1);
1077
- }
1078
- }