cabloy 5.1.219 → 5.1.221

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 (89) hide show
  1. package/.cabloy-version +1 -1
  2. package/.github/workflows/agent-governance.yml +2 -2
  3. package/.github/workflows/create-cabloy.yml +3 -3
  4. package/.github/workflows/docs-pages.yml +2 -2
  5. package/.github/workflows/playwright-e2e.yml +4 -4
  6. package/.github/workflows/vona-cov-pg.yml +2 -2
  7. package/.github/workflows/vona-test-crud.yml +2 -2
  8. package/.github/workflows/vona-test-mysql.yml +2 -2
  9. package/.github/workflows/vona-test-pg.yml +2 -2
  10. package/.github/workflows/vona-test-sqlite3.yml +2 -2
  11. package/.github/workflows/vona-tsc.yml +2 -2
  12. package/.github/workflows/zova-ui.yml +2 -2
  13. package/CHANGELOG.md +23 -0
  14. package/README.md +1 -1
  15. package/package.json +4 -3
  16. package/repo-docs/frontend/openapi-sdk-guide.md +2 -0
  17. package/repo-docs/fullstack/quickstart.md +3 -3
  18. package/repo-docs/reference/repo-scripts.md +16 -0
  19. package/scripts/generateOpenapiIsolated.test.ts +25 -0
  20. package/scripts/generateOpenapiIsolated.ts +46 -12
  21. package/scripts/runIsolatedTest.test.ts +165 -45
  22. package/scripts/runIsolatedTest.ts +111 -24
  23. package/scripts/strictGenerationDiagnostics.test.ts +1009 -0
  24. package/scripts/strictGenerationDiagnostics.ts +61 -0
  25. package/scripts/strictGenerationStartup.test.ts +212 -0
  26. package/vona/package.original.json +3 -2
  27. package/vona/packages-cli/cli/package.json +1 -1
  28. package/vona/packages-cli/cli-set-api/package.json +1 -1
  29. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.dev.ts +14 -4
  30. package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/generateEntryFiles.ts +6 -1
  31. package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/generateVonaMeta.ts +2 -10
  32. package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/validateGenerationPaths.ts +27 -0
  33. package/vona/packages-cli/cli-set-api/test/binDevLifecycle.test.ts +1 -1
  34. package/vona/packages-cli/cli-set-api/test/strictGenerationPrivacy.test.ts +439 -0
  35. package/vona/packages-vona/vona/package.json +1 -1
  36. package/vona/packages-vona/vona-core/package.json +1 -1
  37. package/vona/packages-vona/vona-core/src/lib/bean/beanBase.ts +4 -0
  38. package/vona/packages-vona/vona-core/src/lib/core/asyncLocalStorage.ts +84 -12
  39. package/vona/packages-vona/vona-core/src/lib/core/index.ts +14 -0
  40. package/vona/packages-vona/vona-core/src/lib/core/logger/appLogger.ts +19 -3
  41. package/vona/packages-vona/vona-core/src/lib/core/logger/diagnosticLogger.test.ts +346 -0
  42. package/vona/packages-vona/vona-core/src/lib/core/logger/diagnosticLogger.ts +138 -0
  43. package/vona/packages-vona/vona-core/src/lib/core/logger/index.ts +1 -0
  44. package/vona/packages-vona/vona-core/src/lib/core/logger/utils.ts +25 -5
  45. package/vona/packages-vona/vona-core/src/lib/core/requestBoundary.ts +89 -0
  46. package/vona/packages-vona/vona-core/src/lib/core/testFreshness.test.ts +379 -0
  47. package/vona/packages-vona/vona-core/src/lib/core/testFreshness.ts +232 -0
  48. package/vona/packages-vona/vona-core/src/lib/core/testStrictMode.ts +9 -0
  49. package/vona/packages-vona/vona-core/src/lib/framework/start.test.ts +4 -3
  50. package/vona/packages-vona/vona-core/src/lib/framework/start.ts +2 -0
  51. package/vona/packages-vona/vona-mock/package.json +1 -1
  52. package/vona/pnpm-lock.yaml +691 -356
  53. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  54. package/vona/src/suite-vendor/a-vona/modules/a-executor/package.json +1 -1
  55. package/vona/src/suite-vendor/a-vona/modules/a-executor/src/bean/bean.executor.ts +111 -60
  56. package/vona/src/suite-vendor/a-vona/modules/a-executor/src/service/executor.ts +6 -6
  57. package/vona/src/suite-vendor/a-vona/modules/a-executor/src/types/executor.ts +13 -1
  58. package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
  59. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/lib/jwtClientLogging.test.ts +182 -0
  60. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/service/jwtClient.ts +2 -8
  61. package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
  62. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/bean/aopMethod.log.ts +4 -1
  63. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/bean/bean.logger.ts +9 -0
  64. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/bean/middlewareSystem.httpLog.ts +27 -14
  65. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/lib/redactHttpLog.test.ts +207 -0
  66. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/lib/redactHttpLog.ts +30 -0
  67. package/vona/src/suite-vendor/a-vona/modules/a-logger/test/middlewareSystem.httpLog.test.ts +33 -1
  68. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +1 -1
  69. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/index.ts +11 -0
  70. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/lib/protectedSqliteRegistry.ts +356 -0
  71. package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
  72. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/service/startup.ts +6 -0
  73. package/vona/src/suite-vendor/a-vona/modules/a-startup/test/devSeed.test.ts +2 -2
  74. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/package.json +1 -1
  75. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/src/bean/bean.telemetry.ts +8 -1
  76. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/src/bean/middlewareSystem.trace.ts +9 -14
  77. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/src/lib/spanDiagnostics.ts +70 -0
  78. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/src/service/telemetry.ts +37 -23
  79. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  80. package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/database.ts +31 -4
  81. package/vona/src/suite-vendor/a-vona/package.json +2 -2
  82. package/zova/package.original.json +3 -2
  83. package/zova/packages-cli/cli/package.json +2 -2
  84. package/zova/packages-cli/cli-set-front/package.json +1 -1
  85. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.bin.buildRest.ts +11 -101
  86. package/zova/packages-cli/cli-set-front/src/lib/common/restDependencies.ts +78 -0
  87. package/zova/packages-cli/cli-set-front/src/lib/common/restDependencyVersions.ts +252 -0
  88. package/zova/packages-cli/cli-set-front/test/restDependencies.test.ts +568 -0
  89. package/zova/pnpm-lock.yaml +442 -564
@@ -14,6 +14,13 @@ import {
14
14
  sendTestClaimEvent,
15
15
  startTestClaimBroker,
16
16
  } from '../vona/packages-vona/vona-core/src/lib/core/testClaim.ts';
17
+ import {
18
+ discardNativeOutput,
19
+ guardianStdio,
20
+ reportIsolatedDiagnostic,
21
+ strictGenerationFailure,
22
+ usesStrictGeneration,
23
+ } from './strictGenerationDiagnostics.ts';
17
24
  import {
18
25
  cleanTestClaim,
19
26
  parseTestClaimTtlSeconds,
@@ -94,7 +101,16 @@ export async function startOwnedProcess(
94
101
  cwd: string,
95
102
  env: NodeJS.ProcessEnv,
96
103
  ): Promise<OwnedProcess> {
97
- if (process.platform === 'win32') return startWindowsOwnedProcess(command, args, cwd, env);
104
+ const strict = usesStrictGeneration(env);
105
+ if (process.platform === 'win32') {
106
+ return startWindowsOwnedProcess(
107
+ command,
108
+ args,
109
+ cwd,
110
+ env,
111
+ strict ? discardNativeOutput() : undefined,
112
+ );
113
+ }
98
114
  const processId = randomUUID();
99
115
  const managed = hasTestClaimTransport(env);
100
116
  const registration = { id: processId, role: 'guardian', stage: 'pending' as const };
@@ -102,7 +118,7 @@ export async function startOwnedProcess(
102
118
  const guardian: ChildProcess = spawn(process.execPath, [GUARDIAN_FILE], {
103
119
  cwd: ROOT_DIR,
104
120
  env,
105
- stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
121
+ stdio: guardianStdio(strict),
106
122
  detached: true,
107
123
  });
108
124
  let drained: GuardianResult | undefined;
@@ -335,9 +351,15 @@ export async function withIsolatedVona<T>(
335
351
  callback: () => Promise<T>,
336
352
  dependencies: IsolatedVonaDependencies = { start: startOwnedProcess, ready: waitForReady },
337
353
  ): Promise<T> {
354
+ const strict = usesStrictGeneration(env);
338
355
  const readyKey = randomBytes(32).toString('hex');
339
356
  const command = getIsolatedVonaCommand(port, env, readyKey);
340
- const server = await dependencies.start(command.command, command.args, command.cwd, command.env);
357
+ let server: OwnedProcess;
358
+ try {
359
+ server = await dependencies.start(command.command, command.args, command.cwd, command.env);
360
+ } catch (error) {
361
+ throw strict ? strictGenerationFailure('startup') : error;
362
+ }
341
363
  let stopping = false;
342
364
  let exitedEarly = false;
343
365
  void server.wait().then(
@@ -351,7 +373,9 @@ export async function withIsolatedVona<T>(
351
373
  let interrupted = false;
352
374
  const onInterrupt = () => {
353
375
  interrupted = true;
354
- void server.stop().catch(console.error);
376
+ void server
377
+ .stop()
378
+ .catch(error => reportIsolatedDiagnostic(strict, 'interrupt-stop-failed', error));
355
379
  };
356
380
  process.on('SIGINT', onInterrupt);
357
381
  process.on('SIGTERM', onInterrupt);
@@ -398,19 +422,22 @@ export async function withIsolatedVona<T>(
398
422
  if (interrupted) throw new Error('Isolated Vona run interrupted');
399
423
  result = await callback();
400
424
  } catch (error) {
401
- operationError = toError(error);
425
+ operationError = strict
426
+ ? strictGenerationFailure(ready ? 'operation' : 'startup', error)
427
+ : toError(error);
402
428
  } finally {
403
429
  stopping = true;
404
430
  try {
405
431
  await shutdown();
406
432
  } catch (error) {
407
- shutdownError = toError(error);
433
+ shutdownError = strict ? strictGenerationFailure('shutdown') : toError(error);
408
434
  } finally {
409
435
  process.off('SIGINT', onInterrupt);
410
436
  process.off('SIGTERM', onInterrupt);
411
437
  }
412
438
  }
413
439
  if (operationError && shutdownError) {
440
+ if (strict) throw strictGenerationFailure('operation-and-shutdown');
414
441
  throw new AggregateError(
415
442
  [operationError, shutdownError],
416
443
  'Isolated Vona operation and shutdown failed',
@@ -427,11 +454,19 @@ export async function runIsolatedProcess(
427
454
  cwd: string,
428
455
  env: NodeJS.ProcessEnv,
429
456
  ) {
430
- const child = await startOwnedProcess(command, args, cwd, env);
457
+ const strict = usesStrictGeneration(env);
458
+ let child: OwnedProcess;
459
+ try {
460
+ child = await startOwnedProcess(command, args, cwd, env);
461
+ } catch (error) {
462
+ throw strict ? strictGenerationFailure('generator') : error;
463
+ }
431
464
  let interrupted = false;
432
465
  const onInterrupt = () => {
433
466
  interrupted = true;
434
- void child.stop().catch(console.error);
467
+ void child
468
+ .stop()
469
+ .catch(error => reportIsolatedDiagnostic(strict, 'interrupt-stop-failed', error));
435
470
  };
436
471
  process.on('SIGINT', onInterrupt);
437
472
  process.on('SIGTERM', onInterrupt);
@@ -440,6 +475,8 @@ export async function runIsolatedProcess(
440
475
  if (result.failed || interrupted || result.result?.code !== 0) {
441
476
  throw new Error(`Isolated test exited: ${result.result?.signal ?? result.result?.code}`);
442
477
  }
478
+ } catch (error) {
479
+ throw strict ? strictGenerationFailure('generator') : error;
443
480
  } finally {
444
481
  process.off('SIGINT', onInterrupt);
445
482
  process.off('SIGTERM', onInterrupt);
@@ -546,19 +583,53 @@ export interface IsolatedRunContext {
546
583
  env: NodeJS.ProcessEnv;
547
584
  }
548
585
 
586
+ export interface IsolatedRunOptions {
587
+ skipExpiredClaimReaping?: boolean;
588
+ }
589
+
590
+ export async function reapBeforeIsolatedRun(
591
+ kind: 'unit' | 'cov' | 'e2e' | 'contract',
592
+ vonaDir: string,
593
+ options: IsolatedRunOptions = {},
594
+ reap: typeof reapExpiredTestClaims = reapExpiredTestClaims,
595
+ ): Promise<void> {
596
+ if (options.skipExpiredClaimReaping) {
597
+ if (kind !== 'contract') {
598
+ throw new Error('Skipping expired claim reaping is supported only for contract generation');
599
+ }
600
+ return;
601
+ }
602
+ await reap(vonaDir, {
603
+ ttlSeconds: parseTestClaimTtlSeconds(),
604
+ now: Date.now(),
605
+ isInactive: claim => isTestClaimInactive(claim),
606
+ warn: message => console.error(message),
607
+ });
608
+ }
609
+
549
610
  export async function withIsolatedRun<T>(
550
611
  kind: 'unit' | 'cov' | 'e2e' | 'contract',
551
612
  callback: (context: IsolatedRunContext) => Promise<T>,
552
613
  rootDir = ROOT_DIR,
614
+ options: IsolatedRunOptions = {},
553
615
  ): Promise<T> {
616
+ try {
617
+ return await withIsolatedRunInternal(kind, callback, rootDir, options);
618
+ } catch (error) {
619
+ throw options.skipExpiredClaimReaping ? strictGenerationFailure('preparation', error) : error;
620
+ }
621
+ }
622
+
623
+ async function withIsolatedRunInternal<T>(
624
+ kind: 'unit' | 'cov' | 'e2e' | 'contract',
625
+ callback: (context: IsolatedRunContext) => Promise<T>,
626
+ rootDir: string,
627
+ options: IsolatedRunOptions,
628
+ ): Promise<T> {
629
+ const strict = options.skipExpiredClaimReaping === true;
554
630
  resolveCabloyEdition(rootDir);
555
631
  const vonaDir = resolve(rootDir, 'vona');
556
- await reapExpiredTestClaims(vonaDir, {
557
- ttlSeconds: parseTestClaimTtlSeconds(),
558
- now: Date.now(),
559
- isInactive: claim => isTestClaimInactive(claim),
560
- warn: message => console.error(message),
561
- });
632
+ await reapBeforeIsolatedRun(kind, vonaDir, options);
562
633
  const runId = createTestRunId();
563
634
  const dataRoot = resolve(vonaDir, `.app-test-${runId}`);
564
635
  const generatedRoot = resolve(vonaDir, `.vona-test-${runId}`);
@@ -580,6 +651,7 @@ export async function withIsolatedRun<T>(
580
651
  META_MODE: 'test',
581
652
  VONA_DB_RESET: undefined,
582
653
  VONA_TEST_RUN_ID: runId,
654
+ VONA_TEST_REQUIRE_FRESH_RESOURCES: options.skipExpiredClaimReaping ? 'true' : undefined,
583
655
  VONA_TEST_READY_KEY: undefined,
584
656
  VONA_TEST_SERVER_ORIGIN: undefined,
585
657
  APP_NAME: `cabtest${runId}`,
@@ -611,26 +683,41 @@ export async function withIsolatedRun<T>(
611
683
  await broker?.update({ type: 'status', status: 'failed' }).catch(() => {
612
684
  console.error('Could not record failed test status; claim retained');
613
685
  });
614
- throw error;
686
+ throw strict ? strictGenerationFailure('run', error) : error;
615
687
  } finally {
616
688
  if (!completed) {
617
- console.error(`Isolated test claim and resources retained for inspection: ${claimPath}`);
689
+ reportIsolatedDiagnostic(
690
+ strict,
691
+ 'failed-resources-retained',
692
+ `Isolated test claim and resources retained for inspection: ${claimPath}`,
693
+ );
618
694
  }
619
695
  await broker?.close();
620
696
  }
621
- const cleanup = await cleanTestClaim(claimPath, {
622
- projectPath: vonaDir,
623
- isInactive: claim => isTestClaimInactive(claim, true),
624
- warn: message => console.error(message),
625
- });
626
- if (cleanup.status !== 'cleaned') {
627
- console.error(`Isolated test claim retained for inspection: ${claimPath}`);
628
- throw new Error('Isolated test succeeded but resource cleanup did not complete');
697
+ try {
698
+ const cleanup = await cleanTestClaim(claimPath, {
699
+ projectPath: vonaDir,
700
+ isInactive: claim => isTestClaimInactive(claim, true),
701
+ warn: message => reportIsolatedDiagnostic(strict, 'cleanup-warning', message),
702
+ });
703
+ if (cleanup.status !== 'cleaned') {
704
+ reportIsolatedDiagnostic(
705
+ strict,
706
+ 'cleanup-incomplete-claim-retained',
707
+ `Isolated test claim retained for inspection: ${claimPath}`,
708
+ );
709
+ throw new Error('Isolated test succeeded but resource cleanup did not complete');
710
+ }
711
+ } catch (error) {
712
+ throw strict ? strictGenerationFailure('cleanup') : error;
629
713
  }
630
714
  return result as T;
631
715
  }
632
716
 
633
717
  export async function runIsolatedTest(kind: 'unit' | 'e2e', args: string[]) {
718
+ if (args.some(arg => /^--skip-expired-claim-reaping(?:=|$)/.test(arg))) {
719
+ throw new Error('--skip-expired-claim-reaping is supported only for contract generation');
720
+ }
634
721
  if (process.env.E2E_BASE_URL !== undefined) {
635
722
  throw new Error(
636
723
  'E2E_BASE_URL is unsupported; the E2E runner manages a local test-mode target.',