@makroz/web 1.2.6-rc14 → 1.3.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 (2) hide show
  1. package/bin/mk-update.js +245 -41
  2. package/package.json +2 -2
package/bin/mk-update.js CHANGED
@@ -57,10 +57,125 @@ function getLatestRegistryVersion(packageName) {
57
57
  return 'unknown';
58
58
  }
59
59
 
60
+ function getRegistryVersions(packageName) {
61
+ try {
62
+ const stdout = execSync(`npm view ${packageName} versions --json`, {
63
+ encoding: 'utf8',
64
+ stdio: ['ignore', 'pipe', 'ignore'],
65
+ timeout: 5000,
66
+ });
67
+ if (stdout.trim()) {
68
+ const parsed = JSON.parse(stdout.trim());
69
+ return Array.isArray(parsed) ? parsed : [parsed];
70
+ }
71
+ } catch {
72
+ try {
73
+ const stdout = execSync(`npm view ${packageName} versions`, {
74
+ encoding: 'utf8',
75
+ stdio: ['ignore', 'pipe', 'ignore'],
76
+ timeout: 5000,
77
+ });
78
+ if (stdout.trim()) {
79
+ return stdout.replace(/[\[\]']/g, '').split(',').map(v => v.trim()).filter(Boolean);
80
+ }
81
+ } catch {
82
+ // silent fallback
83
+ }
84
+ }
85
+ return [];
86
+ }
87
+
88
+ function parseVersion(v) {
89
+ const clean = v.replace(/^v/, '');
90
+ const [main, prerelease] = clean.split('-');
91
+ const [major, minor, patch] = main.split('.').map(Number);
92
+ return {
93
+ major: isNaN(major) ? 0 : major,
94
+ minor: isNaN(minor) ? 0 : minor,
95
+ patch: isNaN(patch) ? 0 : patch,
96
+ prerelease: prerelease || null,
97
+ };
98
+ }
99
+
100
+ function compareVersions(v1, v2) {
101
+ const p1 = parseVersion(v1);
102
+ const p2 = parseVersion(v2);
103
+
104
+ if (p1.major !== p2.major) return p1.major - p2.major;
105
+ if (p1.minor !== p2.minor) return p1.minor - p2.minor;
106
+ if (p1.patch !== p2.patch) return p1.patch - p2.patch;
107
+
108
+ if (p1.prerelease && !p2.prerelease) return -1;
109
+ if (!p1.prerelease && p2.prerelease) return 1;
110
+
111
+ if (p1.prerelease && p2.prerelease) {
112
+ const regex = /^([a-zA-Z.-]+)(\d*)$/;
113
+ const m1 = p1.prerelease.match(regex);
114
+ const m2 = p2.prerelease.match(regex);
115
+
116
+ if (m1 && m2) {
117
+ const label1 = m1[1];
118
+ const label2 = m2[1];
119
+ if (label1 !== label2) {
120
+ return label1.localeCompare(label2);
121
+ }
122
+ const num1 = m1[2] ? parseInt(m1[2], 10) : 0;
123
+ const num2 = m2[2] ? parseInt(m2[2], 10) : 0;
124
+ return num1 - num2;
125
+ }
126
+ return p1.prerelease.localeCompare(p2.prerelease);
127
+ }
128
+
129
+ return 0;
130
+ }
131
+
132
+ function performUpdate(updates, packageManager) {
133
+ const pkgJsonPath = path.join(process.cwd(), 'package.json');
134
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
135
+
136
+ const dependencies = pkg.dependencies || {};
137
+ const devDependencies = pkg.devDependencies || {};
138
+
139
+ updates.forEach(upd => {
140
+ const newSpec = upd.isLocal ? `file:../../mk-director/packages/${upd.name.replace('@makroz/', 'mk-')}` : `^${upd.version}`;
141
+ if (dependencies[upd.name]) {
142
+ dependencies[upd.name] = newSpec;
143
+ } else if (devDependencies[upd.name]) {
144
+ devDependencies[upd.name] = newSpec;
145
+ }
146
+ });
147
+
148
+ fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
149
+ console.log('\n✅ package.json actualizado.');
150
+
151
+ let command = '';
152
+ if (packageManager === 'pnpm') {
153
+ command = 'pnpm install';
154
+ } else if (packageManager === 'yarn') {
155
+ command = 'yarn install';
156
+ } else {
157
+ command = 'npm install';
158
+ }
159
+
160
+ console.log(`\nEjecutando: ${command}...\n`);
161
+
162
+ try {
163
+ execSync(command, { stdio: 'inherit' });
164
+ console.log('\n🏁 Actualización finalizada con éxito.\n');
165
+ } catch (e) {
166
+ console.error(`\n❌ Error al ejecutar la actualización: ${e.message}\n`);
167
+ process.exit(1);
168
+ }
169
+ }
170
+
60
171
  async function run() {
61
172
  const args = process.argv.slice(2);
62
173
  const toLocal = args.includes('--local') || args.includes('--dev');
63
174
  const toProd = args.includes('--prod') || args.includes('--registry') || args.includes('--remote');
175
+ const dryRun = args.includes('--dry-run');
176
+
177
+ const cleanArgs = args.filter(arg => !['--local', '--dev', '--prod', '--registry', '--remote', '--dry-run'].includes(arg));
178
+ const targetVersionArg = cleanArgs.find(arg => !arg.startsWith('-'));
64
179
 
65
180
  const pkgJsonPath = path.join(process.cwd(), 'package.json');
66
181
  if (!fs.existsSync(pkgJsonPath)) {
@@ -117,6 +232,10 @@ async function run() {
117
232
  updateSection(devDependencies);
118
233
 
119
234
  if (modified) {
235
+ if (dryRun) {
236
+ console.log('\n[Simulación] Se omitió la escritura en package.json y la ejecución del gestor de paquetes.');
237
+ process.exit(0);
238
+ }
120
239
  fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
121
240
  console.log('\n✅ package.json actualizado correctamente.');
122
241
  const packageManager = detectPackageManager();
@@ -159,37 +278,44 @@ async function run() {
159
278
  const isLocal = spec.startsWith('file:');
160
279
  const installed = getInstalledVersion(name);
161
280
 
162
- let latest = 'unknown';
281
+ let versions = [];
282
+ let latestStable = 'unknown';
283
+
163
284
  if (isLocal) {
164
- latest = getLatestLocalVersion(spec);
285
+ const localVersion = getLatestLocalVersion(spec);
286
+ if (localVersion !== 'unknown') {
287
+ versions = [localVersion];
288
+ }
165
289
  } else {
166
- latest = getLatestRegistryVersion(name);
290
+ versions = getRegistryVersions(name);
291
+ latestStable = getLatestRegistryVersion(name);
167
292
  }
168
293
 
169
- // Compare versions to see if update is needed
170
- let needsUpdate = false;
171
- if (installed !== 'unknown' && latest !== 'unknown') {
172
- needsUpdate = installed !== latest;
173
- } else if (installed === 'unknown' && latest !== 'unknown') {
174
- needsUpdate = true;
294
+ let higherVersions = [];
295
+ if (installed !== 'unknown') {
296
+ higherVersions = versions.filter(v => compareVersions(v, installed) > 0);
297
+ } else {
298
+ higherVersions = versions;
175
299
  }
176
300
 
301
+ higherVersions.sort((a, b) => compareVersions(b, a));
302
+
177
303
  packageInfos.push({
178
304
  name,
179
305
  currentSpec: spec,
180
306
  installedVersion: installed,
181
- latestVersion: latest,
307
+ higherVersions,
308
+ latestStable,
182
309
  isLocal,
183
- needsUpdate,
310
+ needsUpdate: higherVersions.length > 0,
184
311
  });
185
312
  }
186
313
 
187
- // Print summary of packages
188
314
  console.log('Estado de los paquetes:');
189
315
  for (const info of packageInfos) {
190
316
  const typeLabel = info.isLocal ? '[Local]' : '[Registry]';
191
317
  if (info.needsUpdate) {
192
- console.log(` ⚠️ ${info.name} ${typeLabel}: ${info.installedVersion} -> ${info.latestVersion} (Actualización disponible)`);
318
+ console.log(` ⚠️ ${info.name} ${typeLabel}: ${info.installedVersion} -> ${info.higherVersions[0]} (Actualizaciones disponibles: ${info.higherVersions.length})`);
193
319
  } else {
194
320
  console.log(` ✅ ${info.name} ${typeLabel}: ${info.installedVersion} (Al día)`);
195
321
  }
@@ -205,45 +331,123 @@ async function run() {
205
331
  const packageManager = detectPackageManager();
206
332
  console.log(`\nGestor de paquetes detectado: ${packageManager}`);
207
333
 
334
+ if (targetVersionArg) {
335
+ const targetVersionClean = targetVersionArg.replace(/^v/, '');
336
+ console.log(`\n📌 Versión especificada por argumento: v${targetVersionClean}`);
337
+
338
+ if (dryRun) {
339
+ console.log(`[Simulación] Se actualizarían los siguientes paquetes a v${targetVersionClean}:`);
340
+ updatable.forEach(info => console.log(` - ${info.name}`));
341
+ process.exit(0);
342
+ }
343
+
344
+ const rl = readline.createInterface({
345
+ input: process.stdin,
346
+ output: process.stdout,
347
+ });
348
+
349
+ rl.question(`\n¿Confirmás la actualización a v${targetVersionClean}? (Y/n): `, (answer) => {
350
+ rl.close();
351
+ if (answer.trim().toLowerCase() === 'n') {
352
+ console.log('Actualización cancelada.');
353
+ process.exit(0);
354
+ }
355
+ performUpdate(updatable.map(info => ({ name: info.name, version: targetVersionClean, isLocal: info.isLocal })), packageManager);
356
+ });
357
+ return;
358
+ }
359
+
208
360
  const rl = readline.createInterface({
209
361
  input: process.stdin,
210
362
  output: process.stdout,
211
363
  });
212
364
 
213
- rl.question('\n¿Querés actualizar los paquetes? (Y/n): ', (answer) => {
214
- rl.close();
215
- const confirmed = answer.trim().toLowerCase() !== 'n';
365
+ const selectedUpdates = [];
216
366
 
217
- if (!confirmed) {
218
- console.log('Actualización cancelada por el usuario.');
219
- process.exit(0);
220
- }
367
+ async function askPackageUpdate(index) {
368
+ if (index >= updatable.length) {
369
+ rl.close();
370
+ if (selectedUpdates.length === 0) {
371
+ console.log('No se seleccionó ninguna actualización.');
372
+ process.exit(0);
373
+ }
221
374
 
222
- const packageNames = updatable.map(info => info.name);
223
- let command = '';
375
+ console.log('\nSelección de actualizaciones:');
376
+ selectedUpdates.forEach(upd => {
377
+ console.log(` - ${upd.name} -> v${upd.version}`);
378
+ });
224
379
 
225
- if (packageManager === 'pnpm') {
226
- command = `pnpm update ${packageNames.join(' ')}`;
227
- } else if (packageManager === 'yarn') {
228
- command = `yarn upgrade ${packageNames.join(' ')}`;
229
- } else {
230
- // npm
231
- const args = updatable.map(info => {
232
- return info.isLocal ? info.name : `${info.name}@latest`;
233
- }).join(' ');
234
- command = `npm install ${args}`;
235
- }
380
+ if (dryRun) {
381
+ console.log('\n[Simulación] Se omitirá la descarga e instalación.');
382
+ process.exit(0);
383
+ }
236
384
 
237
- console.log(`\nEjecutando: ${command}...\n`);
385
+ const confirmRl = readline.createInterface({
386
+ input: process.stdin,
387
+ output: process.stdout,
388
+ });
238
389
 
239
- try {
240
- execSync(command, { stdio: 'inherit' });
241
- console.log('\n🏁 Actualización finalizada con éxito.\n');
242
- } catch (e) {
243
- console.error(`\n❌ Error al ejecutar la actualización: ${e.message}\n`);
244
- process.exit(1);
390
+ confirmRl.question('\n¿Confirmás la actualización? (Y/n): ', (answer) => {
391
+ confirmRl.close();
392
+ if (answer.trim().toLowerCase() === 'n') {
393
+ console.log('Actualización cancelada.');
394
+ process.exit(0);
395
+ }
396
+ performUpdate(selectedUpdates, packageManager);
397
+ });
398
+ return;
245
399
  }
246
- });
400
+
401
+ const info = updatable[index];
402
+ console.log(`\n----------------------------------------`);
403
+ console.log(`¿A qué versión querés actualizar ${info.name}? (Actual: ${info.installedVersion})`);
404
+
405
+ const choices = info.higherVersions.map((version, i) => {
406
+ const isLatestStable = version === info.latestStable;
407
+ const isRc = /rc|alpha|beta/i.test(version);
408
+ const marker = isLatestStable ? ' ⭐ (última estable)' : (isRc ? ' 🧪 (pre-release)' : '');
409
+ return {
410
+ text: `v${version}${marker}`,
411
+ version,
412
+ };
413
+ });
414
+
415
+ choices.forEach((choice, i) => {
416
+ console.log(` [${i + 1}] ${choice.text}`);
417
+ });
418
+ console.log(` [s] Omitir este paquete`);
419
+
420
+ rl.question(`\nIngresá el número de opción (1-${choices.length}) o 's' para omitir [default 1]: `, (ans) => {
421
+ const cleanAns = ans.trim();
422
+ if (cleanAns.toLowerCase() === 's') {
423
+ console.log(`Omitiendo ${info.name}.`);
424
+ askPackageUpdate(index + 1);
425
+ return;
426
+ }
427
+
428
+ let choiceIndex = 0;
429
+ if (cleanAns !== '') {
430
+ const parsedAns = parseInt(cleanAns, 10);
431
+ if (isNaN(parsedAns) || parsedAns < 1 || parsedAns > choices.length) {
432
+ console.log('Opción inválida. Reintentando...');
433
+ askPackageUpdate(index);
434
+ return;
435
+ }
436
+ choiceIndex = parsedAns - 1;
437
+ }
438
+
439
+ const selectedVersion = choices[choiceIndex].version;
440
+ selectedUpdates.push({
441
+ name: info.name,
442
+ version: selectedVersion,
443
+ isLocal: info.isLocal,
444
+ });
445
+
446
+ askPackageUpdate(index + 1);
447
+ });
448
+ }
449
+
450
+ askPackageUpdate(0);
247
451
  }
248
452
 
249
453
  run();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makroz/web",
3
- "version": "1.2.6-rc14",
3
+ "version": "1.3.0",
4
4
  "description": "React UI components and hooks for MK-Director web applications",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@tanstack/react-query": "^5.62.0",
36
- "@makroz/core": "1.1.6-rc14"
36
+ "@makroz/core": "1.2.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "next": "^16.0.0",