cabloy 5.1.81 → 5.1.83

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.83
4
+
5
+ ### Bug Fixes
6
+
7
+ - Automate refresh of the zova-core compensation graph.
8
+ - Harden zova-core compensation rollback handling.
9
+
3
10
  ## 5.1.81
4
11
 
5
12
  ### Improvements
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.81",
3
+ "version": "5.1.83",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -1,6 +1,14 @@
1
1
  import minimist from 'minimist';
2
2
  import { execSync } from 'node:child_process';
3
- import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import {
4
+ copyFileSync,
5
+ existsSync,
6
+ mkdirSync,
7
+ readFileSync,
8
+ readdirSync,
9
+ rmSync,
10
+ writeFileSync,
11
+ } from 'node:fs';
4
12
  import { dirname, resolve } from 'node:path';
5
13
  import { fileURLToPath } from 'node:url';
6
14
 
@@ -11,8 +19,16 @@ const COMMIT_CAP = 200;
11
19
  const RELEASE_SCRIPT_PATH = fileURLToPath(import.meta.url);
12
20
  const ROOT_DIR = resolve(dirname(RELEASE_SCRIPT_PATH), '..');
13
21
  const VONA_DIR = resolve(ROOT_DIR, 'vona');
22
+ const VONA_PACKAGE_JSON_PATH = resolve(VONA_DIR, 'package.json');
23
+ const VONA_PACKAGE_ORIGINAL_JSON_PATH = resolve(VONA_DIR, 'package.original.json');
14
24
  const VONA_WORKSPACE_PATH = resolve(VONA_DIR, 'pnpm-workspace.yaml');
25
+ const VONA_LOCKFILE_PATH = resolve(VONA_DIR, 'pnpm-lock.yaml');
15
26
  const VONA_PATCHES_DIR = resolve(VONA_DIR, 'patches');
27
+ const VONA_ZOVA_REST_DIR = resolve(VONA_DIR, '.zova-rest');
28
+ const ZOVA_DIR = resolve(ROOT_DIR, 'zova');
29
+ const ZOVA_PACKAGE_JSON_PATH = resolve(ZOVA_DIR, 'package.json');
30
+ const ZOVA_PACKAGE_ORIGINAL_JSON_PATH = resolve(ZOVA_DIR, 'package.original.json');
31
+ const ZOVA_LOCKFILE_PATH = resolve(ZOVA_DIR, 'pnpm-lock.yaml');
16
32
  const ZOVA_CORE_PACKAGE_JSON_PATH = resolve(
17
33
  ROOT_DIR,
18
34
  'zova',
@@ -22,12 +38,22 @@ const ZOVA_CORE_PACKAGE_JSON_PATH = resolve(
22
38
  );
23
39
  const PACKAGE_JSON_PATH = resolve(ROOT_DIR, 'package.json');
24
40
  const CHANGELOG_PATH = resolve(ROOT_DIR, 'CHANGELOG.md');
41
+ const ZOVA_CORE_PATCH_TARGETS = [
42
+ 'dist/bean/resource/error/errorGlobal.d.ts',
43
+ 'dist/types/utils/env.d.ts',
44
+ 'dist/types/interface/module.d.ts',
45
+ ] as const;
25
46
 
26
47
  interface ExecOptions {
27
48
  cwd?: string;
28
49
  env?: NodeJS.ProcessEnv;
29
50
  }
30
51
 
52
+ interface FileSnapshot {
53
+ filePath: string;
54
+ content: string | null;
55
+ }
56
+
31
57
  // --- Utility functions ---
32
58
  function exec(cmd: string, dryRun?: boolean, options?: ExecOptions): string {
33
59
  if (dryRun) {
@@ -187,9 +213,98 @@ function updateVonaPatchedDependency(version?: string): void {
187
213
  writeFileSync(VONA_WORKSPACE_PATH, `${newLines.join('\n').replace(/\n+$/, '\n')}\n`);
188
214
  }
189
215
 
190
- function ensureFileExists(filePath: string): void {
191
- if (!existsSync(filePath)) {
192
- writeFileSync(filePath, '');
216
+ function readFileIfExists(filePath: string): string | null {
217
+ return existsSync(filePath) ? readFileSync(filePath, 'utf-8') : null;
218
+ }
219
+
220
+ function restoreFileSnapshot(snapshot: FileSnapshot): void {
221
+ if (snapshot.content === null) {
222
+ rmSync(snapshot.filePath, { force: true });
223
+ return;
224
+ }
225
+ writeFileSync(snapshot.filePath, snapshot.content);
226
+ }
227
+
228
+ function createFileSnapshot(filePath: string): FileSnapshot {
229
+ return {
230
+ filePath,
231
+ content: readFileIfExists(filePath),
232
+ };
233
+ }
234
+
235
+ function seedVonaZovaRestWorkspaceDependencies(): void {
236
+ if (!existsSync(VONA_ZOVA_REST_DIR)) return;
237
+ const pkg = readJson(VONA_PACKAGE_JSON_PATH) as {
238
+ dependencies?: Record<string, string>;
239
+ };
240
+ pkg.dependencies ??= {};
241
+ let changed = false;
242
+ for (const entry of readdirSync(VONA_ZOVA_REST_DIR, { withFileTypes: true })) {
243
+ if (!entry.isDirectory()) continue;
244
+ const depName = `zova-rest-${entry.name}`;
245
+ const depValue = 'workspace:^';
246
+ if (pkg.dependencies[depName] === depValue) continue;
247
+ pkg.dependencies[depName] = depValue;
248
+ changed = true;
249
+ }
250
+ if (!changed) return;
251
+ writeFileSync(VONA_PACKAGE_JSON_PATH, `${JSON.stringify(pkg, null, 2)}\n`);
252
+ }
253
+
254
+ function refreshZovaDependencyGraph(): void {
255
+ copyFileSync(ZOVA_PACKAGE_ORIGINAL_JSON_PATH, ZOVA_PACKAGE_JSON_PATH);
256
+ execInherited('pnpm install', false, { cwd: ZOVA_DIR });
257
+ execInherited('npm run zova :tools:deps', false, { cwd: ZOVA_DIR });
258
+ execInherited('npm run build:zova:admin');
259
+ if (existsSync(resolve(ROOT_DIR, '__CABLOY_BASIC__'))) {
260
+ execInherited('npm run build:zova:web');
261
+ }
262
+ }
263
+
264
+ function prepareVonaBootstrapManifest(): void {
265
+ copyFileSync(VONA_PACKAGE_ORIGINAL_JSON_PATH, VONA_PACKAGE_JSON_PATH);
266
+ seedVonaZovaRestWorkspaceDependencies();
267
+ }
268
+
269
+ function refreshVonaDependencyGraph(): void {
270
+ prepareVonaBootstrapManifest();
271
+ execInherited('npm run deps:vona');
272
+ }
273
+
274
+ function validateGeneratedZovaCorePatch(version: string): void {
275
+ const patchFilePath = getPatchFilePath(version);
276
+ const patchContent = readFileIfExists(patchFilePath)?.trim();
277
+ if (!patchContent) {
278
+ throw new Error(`Generated zova-core patch is missing or empty: ${patchFilePath}`);
279
+ }
280
+ if (!patchContent.includes('diff --git')) {
281
+ throw new Error(`Generated zova-core patch does not contain any diff hunks: ${patchFilePath}`);
282
+ }
283
+ for (const patchTarget of ZOVA_CORE_PATCH_TARGETS) {
284
+ if (!patchContent.includes(`a/${patchTarget}`) || !patchContent.includes(`b/${patchTarget}`)) {
285
+ throw new Error(`Generated zova-core patch is missing the expected target: ${patchTarget}`);
286
+ }
287
+ }
288
+ if (!patchContent.includes(' export {};')) {
289
+ throw new Error('Generated zova-core patch is missing the expected errorGlobal export rewrite');
290
+ }
291
+ if (!patchContent.includes("-declare module '@cabloy/module-info'")) {
292
+ throw new Error(
293
+ 'Generated zova-core patch is missing the expected @cabloy/module-info removal',
294
+ );
295
+ }
296
+ if (
297
+ !patchContent.includes('-declare global {') ||
298
+ !patchContent.includes('- interface ProcessEnv {')
299
+ ) {
300
+ throw new Error('Generated zova-core patch is missing the expected ProcessEnv removal');
301
+ }
302
+ }
303
+
304
+ function ensurePatchedLockfileVersion(version: string): void {
305
+ const lockfileContent = readFileIfExists(VONA_LOCKFILE_PATH);
306
+ if (!lockfileContent?.includes(`zova-core@${version}:`)) {
307
+ throw new Error(`Vona lockfile is missing the patched zova-core@${version} entry`);
193
308
  }
194
309
  }
195
310
 
@@ -228,7 +343,7 @@ function applyKnownZovaCorePatchEdits(editDir: string): void {
228
343
  const envContent = readFileSync(envPath, 'utf-8');
229
344
  const envNext = replaceOrThrow(
230
345
  envContent,
231
- /declare global \{\n {4}namespace NodeJS \{\n {8}interface ProcessEnv \{[\s\S]*?\n \}\n \}\n\}\n?/,
346
+ /declare global \{\n {4}namespace NodeJS \{\n {8}interface ProcessEnv \{[\s\S]*?\n {8}\}\n {4}\}\n\}\n?/,
232
347
  '',
233
348
  'the NodeJS.ProcessEnv augmentation',
234
349
  );
@@ -281,56 +396,105 @@ function regenerateVonaZovaCorePatch(
281
396
  console.log(`\n🩹 Regenerating the Vona zova-core patch for ${targetVersion}...`);
282
397
 
283
398
  if (dryRun) {
399
+ // eslint-disable-next-line
400
+ console.log(' [dry-run] Refresh the Zova dependency graph from package.original.json');
401
+ // eslint-disable-next-line
402
+ console.log(' [dry-run] Run pnpm install in zova');
403
+ // eslint-disable-next-line
404
+ console.log(' [dry-run] Run npm run zova :tools:deps in zova');
405
+ // eslint-disable-next-line
406
+ console.log(' [dry-run] Run npm run build:zova:admin');
407
+ // eslint-disable-next-line
408
+ console.log(' [dry-run] Run npm run build:zova:web when the active edition requires it');
409
+ // eslint-disable-next-line
410
+ console.log(' [dry-run] Refresh the Vona dependency graph from package.original.json');
284
411
  // eslint-disable-next-line
285
412
  console.log(
286
413
  ' [dry-run] Temporarily remove the current zova-core patched dependency registration',
287
414
  );
288
- exec(`pnpm --dir "${VONA_DIR}" install`, true);
289
- exec(
290
- `pnpm --dir "${VONA_DIR}" patch zova-core@${targetVersion} --edit-dir "${editDir}" --ignore-existing`,
415
+ // eslint-disable-next-line
416
+ console.log(' [dry-run] Seed Vona .zova-rest workspace dependencies if needed');
417
+ // eslint-disable-next-line
418
+ console.log(' [dry-run] Run npm run deps:vona');
419
+ // eslint-disable-next-line
420
+ console.log(' [dry-run] Run pnpm install in vona without the old patch registration');
421
+ execInherited('pnpm install', true, { cwd: VONA_DIR });
422
+ execInherited(
423
+ `pnpm patch zova-core@${targetVersion} --edit-dir "${editDir}" --ignore-existing`,
291
424
  true,
425
+ { cwd: VONA_DIR },
292
426
  );
293
427
  // eslint-disable-next-line
294
428
  console.log(' [dry-run] Apply the known zova-core declaration-file patch edits');
429
+ execInherited(`pnpm patch-commit "${editDir}" --patches-dir "${VONA_PATCHES_DIR}"`, true, {
430
+ cwd: VONA_DIR,
431
+ });
295
432
  // eslint-disable-next-line
296
- console.log(` [dry-run] Ensure ${newPatchFilePath} exists before patch-commit`);
297
- exec(
298
- `pnpm --dir "${VONA_DIR}" patch-commit "${editDir}" --patches-dir "${VONA_PATCHES_DIR}"`,
299
- true,
300
- );
433
+ console.log(` [dry-run] Validate ${newPatchFilePath}`);
301
434
  // eslint-disable-next-line
302
435
  console.log(` [dry-run] Restore ${VONA_WORKSPACE_PATH} to point at ${newPatchFilePath}`);
303
436
  // eslint-disable-next-line
304
437
  console.log(` [dry-run] Remove ${oldPatchFilePath} if it still exists`);
305
- exec(`pnpm --dir "${VONA_DIR}" install`, true);
438
+ execInherited('pnpm install', true, { cwd: VONA_DIR });
306
439
  return;
307
440
  }
308
441
 
442
+ const snapshots = [
443
+ createFileSnapshot(ZOVA_PACKAGE_JSON_PATH),
444
+ createFileSnapshot(ZOVA_LOCKFILE_PATH),
445
+ createFileSnapshot(VONA_PACKAGE_JSON_PATH),
446
+ createFileSnapshot(VONA_WORKSPACE_PATH),
447
+ createFileSnapshot(VONA_LOCKFILE_PATH),
448
+ createFileSnapshot(oldPatchFilePath),
449
+ createFileSnapshot(newPatchFilePath),
450
+ ];
451
+
309
452
  rmSync(editDir, { recursive: true, force: true });
310
453
  mkdirSync(dirname(editDir), { recursive: true });
311
454
 
312
455
  try {
456
+ refreshZovaDependencyGraph();
313
457
  updateVonaPatchedDependency();
314
- execInherited(`pnpm --dir "${VONA_DIR}" install`);
458
+ refreshVonaDependencyGraph();
459
+ execInherited('pnpm install', false, { cwd: VONA_DIR });
315
460
 
316
461
  execInherited(
317
- `pnpm --dir "${VONA_DIR}" patch zova-core@${targetVersion} --edit-dir "${editDir}" --ignore-existing`,
462
+ `pnpm patch zova-core@${targetVersion} --edit-dir "${editDir}" --ignore-existing`,
463
+ false,
464
+ {
465
+ cwd: VONA_DIR,
466
+ },
318
467
  );
319
468
  applyKnownZovaCorePatchEdits(editDir);
320
-
321
- ensureFileExists(newPatchFilePath);
322
- execInherited(
323
- `pnpm --dir "${VONA_DIR}" patch-commit "${editDir}" --patches-dir "${VONA_PATCHES_DIR}"`,
324
- );
469
+ execInherited(`pnpm patch-commit "${editDir}" --patches-dir "${VONA_PATCHES_DIR}"`, false, {
470
+ cwd: VONA_DIR,
471
+ });
472
+ validateGeneratedZovaCorePatch(targetVersion);
325
473
 
326
474
  updateVonaPatchedDependency(targetVersion);
327
- if (!existsSync(newPatchFilePath)) {
328
- throw new Error(`Expected regenerated patch file is missing: ${newPatchFilePath}`);
329
- }
330
475
  if (currentPatchedVersion !== targetVersion && existsSync(oldPatchFilePath)) {
331
476
  rmSync(oldPatchFilePath);
332
477
  }
333
- execInherited(`pnpm --dir "${VONA_DIR}" install`);
478
+ execInherited('pnpm install', false, { cwd: VONA_DIR });
479
+ if (readCurrentPatchedZovaCoreVersion() !== targetVersion) {
480
+ throw new Error(
481
+ `Vona patchedDependencies entry was not updated to zova-core@${targetVersion}`,
482
+ );
483
+ }
484
+ ensurePatchedLockfileVersion(targetVersion);
485
+ } catch (error) {
486
+ for (const snapshot of snapshots) {
487
+ restoreFileSnapshot(snapshot);
488
+ }
489
+ try {
490
+ execInherited(`pnpm --dir "${VONA_DIR}" install`);
491
+ } catch {
492
+ // eslint-disable-next-line
493
+ console.warn(
494
+ 'Warning: failed to restore the Vona install state after compensation rollback.',
495
+ );
496
+ }
497
+ throw error;
334
498
  } finally {
335
499
  rmSync(editDir, { recursive: true, force: true });
336
500
  }
@@ -352,10 +516,13 @@ function verifyCompensationPatch(dryRun?: boolean): void {
352
516
  function commitCompensationChanges(targetVersion: string, dryRun?: boolean): void {
353
517
  // eslint-disable-next-line
354
518
  console.log('\nšŸ“ Committing compensation changes...');
355
- exec('git add vona/pnpm-workspace.yaml vona/pnpm-lock.yaml vona/patches', dryRun);
519
+ exec(
520
+ 'git add vona/package.json vona/pnpm-workspace.yaml vona/pnpm-lock.yaml vona/patches',
521
+ dryRun,
522
+ );
356
523
  if (!dryRun) {
357
524
  const staged = execSync(
358
- 'git diff --cached --name-only -- vona/pnpm-workspace.yaml vona/pnpm-lock.yaml vona/patches',
525
+ 'git diff --cached --name-only -- vona/package.json vona/pnpm-workspace.yaml vona/pnpm-lock.yaml vona/patches',
359
526
  { cwd: ROOT_DIR, encoding: 'utf-8' },
360
527
  ).trim();
361
528
  if (!staged) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-jsx",
3
- "version": "1.1.70",
3
+ "version": "1.1.71",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "Zova JSX",
6
6
  "keywords": [
@@ -50,7 +50,7 @@
50
50
  "@cabloy/word-utils": "^2.1.14",
51
51
  "typestyle": "^2.4.0",
52
52
  "vue": "^3.5.38",
53
- "zova-core": "^5.1.66"
53
+ "zova-core": "^5.1.68"
54
54
  },
55
55
  "devDependencies": {
56
56
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova",
3
- "version": "5.1.122",
3
+ "version": "5.1.123",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -45,8 +45,8 @@
45
45
  "postpack": "clean-package restore"
46
46
  },
47
47
  "dependencies": {
48
- "zova-core": "^5.1.66",
49
- "zova-suite-a-zova": "^5.1.121"
48
+ "zova-core": "^5.1.68",
49
+ "zova-suite-a-zova": "^5.1.122"
50
50
  },
51
51
  "devDependencies": {
52
52
  "clean-package": "^2.2.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-core",
3
- "version": "5.1.66",
3
+ "version": "5.1.68",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A vue3 framework with ioc",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-module-a-zova",
3
- "version": "5.1.85",
3
+ "version": "5.1.86",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  "@cabloy/word-utils": "^2.1.14",
44
44
  "defu": "^6.1.7",
45
45
  "luxon": "^3.7.2",
46
- "zova-jsx": "^1.1.70"
46
+ "zova-jsx": "^1.1.71"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@cabloy/cli": "^3.1.27",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zova-suite-a-zova",
3
- "version": "5.1.121",
3
+ "version": "5.1.122",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "zova",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "zova-module-a-style": "^5.1.32",
33
33
  "zova-module-a-table": "^5.1.37",
34
34
  "zova-module-a-zod": "^5.1.35",
35
- "zova-module-a-zova": "^5.1.85"
35
+ "zova-module-a-zova": "^5.1.86"
36
36
  },
37
37
  "title": "a-zova"
38
38
  }