cabloy 5.1.203 → 5.1.205
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/.cabloy-version +1 -1
- package/.gitignore +2 -0
- package/CHANGELOG.md +21 -0
- package/lint-staged.config.mjs +2 -0
- package/oxfmt.config.ts +2 -0
- package/oxlint.config.ts +2 -0
- package/package.json +6 -5
- package/repo-agent-governance/managed-assets.json +9 -9
- package/repo-agent-governance/policies/repository.md +5 -2
- package/repo-agent-governance/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +2 -2
- package/repo-agent-governance/skills/cabloy-workflow/SKILL.md +2 -0
- package/repo-docs/backend/migration-and-changes.md +13 -12
- package/repo-docs/backend/orm-select-guide.md +6 -0
- package/repo-docs/backend/runtime-and-flavors.md +2 -1
- package/repo-docs/backend/transaction-guide.md +12 -0
- package/repo-docs/backend/unit-testing.md +12 -8
- package/repo-docs/blogs/ai-coding-one-prompt-crud-ssr-multitasking/cover-en-v1.png +0 -0
- package/repo-docs/blogs/ai-coding-one-prompt-crud-ssr-multitasking/images/completion-summary.jpg +0 -0
- package/repo-docs/blogs/ai-coding-one-prompt-crud-ssr-multitasking/images/multitasking-draft.jpg +0 -0
- package/repo-docs/blogs/ai-coding-one-prompt-crud-ssr-multitasking/images/ssr-refresh.jpg +0 -0
- package/repo-docs/blogs/ai-coding-one-prompt-crud-ssr-multitasking/index.md +216 -0
- package/repo-docs/blogs/index.md +15 -0
- package/repo-docs/frontend/scripts.md +1 -1
- package/repo-docs/fullstack/parallel-worktree-environment.md +6 -6
- package/repo-docs/fullstack/ssr-entry-modes.md +19 -0
- package/repo-docs/index.md +2 -0
- package/repo-docs/reference/repo-scripts.md +22 -1
- package/repo-e2e/config/playwright.config.ts +32 -14
- package/repo-e2e/docs/specs/blogs-index.spec.ts +23 -6
- package/repo-e2e/scripts/e2e.test.ts +39 -0
- package/repo-e2e/scripts/e2e.ts +19 -1
- package/repo-e2e/scripts/managedTest.test.ts +389 -0
- package/repo-e2e/scripts/managedTest.ts +210 -0
- package/repo-e2e/scripts/managedTestImports.test.ts +74 -0
- package/repo-e2e/scripts/managedTestImports.ts +110 -0
- package/repo-e2e/scripts/runE2e.ts +12 -1
- package/repo-e2e/scripts/startE2eVona.ts +37 -5
- package/repo-e2e/specs/a-commerce.spec.ts +1 -1
- package/repo-e2e/specs/cabloy-basic.spec.ts +1 -1
- package/repo-e2e/specs/controller-boundary.spec.ts +1 -1
- package/repo-e2e/specs/home-user-account.spec.ts +2 -1
- package/repo-e2e/specs/markdown.spec.ts +1 -1
- package/repo-e2e/specs/routed-dialog.spec.ts +1 -1
- package/scripts/runIsolatedTest.test.ts +426 -0
- package/scripts/runIsolatedTest.ts +454 -0
- package/scripts/testClaimCleanup.test.ts +346 -0
- package/scripts/testClaimCleanup.ts +375 -0
- package/scripts/testClaimProcesses.test.ts +106 -0
- package/scripts/testClaimProcesses.ts +129 -0
- package/scripts/testProcessGuardian.ts +163 -0
- package/scripts/upgrade.ts +1 -16
- package/vona/oxfmt.config.ts +2 -0
- package/vona/oxlint.config.ts +2 -0
- package/vona/package.original.json +2 -2
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli/src/play.test.ts +37 -0
- package/vona/packages-cli/cli/src/play.ts +23 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.dbReset.ts +16 -7
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.dev.ts +13 -7
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.play.ts +5 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.test.ts +12 -7
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/configUtils.ts +21 -2
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/generateVonaMeta.ts +10 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/resolveTestCleanupConfig.test.ts +153 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/resolveTestCleanupConfig.ts +141 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/testCleanupAdapters.test.ts +148 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/testCleanupAdapters.ts +127 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/testCleanupProcess.test.ts +47 -0
- package/vona/packages-cli/cli-set-api/src/lib/bean/toolsBin/testCleanupProcess.ts +139 -0
- package/vona/packages-cli/cli-set-api/src/lib/utils.ts +2 -3
- package/vona/packages-cli/cli-set-api/templates/config/_tsconfig_project.json +1 -0
- package/vona/packages-cli/cli-set-api/templates/config/_tsconfig_source.json +1 -0
- package/vona/packages-cli/cli-set-api/test/binDevMode.test.ts +18 -0
- package/vona/packages-cli/cli-set-api/toolsIsolate/dbReset.ts +15 -2
- package/vona/packages-cli/cli-set-api/tsconfig.build.json +2 -1
- package/vona/packages-utils/babel-plugin-vona-bean-module/package.json +1 -1
- package/vona/packages-utils/babel-plugin-vona-bean-module/src/index.test.ts +16 -0
- package/vona/packages-utils/babel-plugin-vona-bean-module/src/index.ts +3 -2
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/packages-vona/vona-core/package.json +1 -1
- package/vona/packages-vona/vona-core/src/lib/addon/sqlite3.ts +1 -1
- package/vona/packages-vona/vona-core/src/lib/core/config.ts +44 -6
- package/vona/packages-vona/vona-core/src/lib/core/configCleanup.test.ts +40 -0
- package/vona/packages-vona/vona-core/src/lib/core/index.ts +3 -0
- package/vona/packages-vona/vona-core/src/lib/core/isolationGuard.test.ts +301 -0
- package/vona/packages-vona/vona-core/src/lib/core/isolationGuard.ts +312 -0
- package/vona/packages-vona/vona-core/src/lib/core/testClaim.test.ts +577 -0
- package/vona/packages-vona/vona-core/src/lib/core/testClaim.ts +985 -0
- package/vona/packages-vona/vona-core/src/lib/core/testIsolation.ts +129 -0
- package/vona/packages-vona/vona-core/src/lib/framework/createApp.ts +2 -0
- package/vona/packages-vona/vona-core/src/lib/framework/start.ts +4 -0
- package/vona/packages-vona/vona-core/src/lib/framework/useApp.ts +5 -1
- package/vona/packages-vona/vona-core/src/types/application/app.ts +2 -0
- package/vona/packages-vona/vona-core/src/types/utils/env.ts +1 -0
- package/vona/packages-vona/vona-mock/package.json +1 -1
- package/vona/pnpm-lock.yaml +40 -40
- package/vona/src/suite/a-commerce/modules/commerce-payment/test/paymentIndexes.test.ts +73 -10
- package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-logger/src/bean/middlewareSystem.httpLog.ts +15 -1
- package/vona/src/suite-vendor/a-vona/modules/a-logger/src/lib/redactIsolatedReadyHeader.test.ts +24 -0
- package/vona/src/suite-vendor/a-vona/modules/a-logger/src/lib/redactIsolatedReadyHeader.ts +11 -0
- package/vona/src/suite-vendor/a-vona/modules/a-metrics/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-metrics/src/bean/middlewareSystem.health.ts +15 -0
- package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/extend/schemaBuilder.ts +11 -4
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/databaseClient_.ts +6 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.betterSqlite3.ts +41 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.mysql.ts +4 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.pg.ts +2 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-redis/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-redis/src/lib/redis.ts +8 -0
- package/vona/src/suite-vendor/a-vona/modules/a-redis/src/service/redis.ts +23 -6
- package/vona/src/suite-vendor/a-vona/modules/a-redis/src/service/redisClient_.ts +18 -1
- package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-startup/src/service/startup.ts +43 -15
- package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-version/src/lib/databaseTestName.ts +3 -37
- package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/database.ts +93 -15
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/vona/tsconfig.json +1 -0
- package/scripts/initTestData.ts +0 -25
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fse from 'fs-extra';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { lstatSync } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
export const TEST_RUN_ID_ENV = 'VONA_TEST_RUN_ID';
|
|
7
|
+
export const TEST_RUN_OWNER_FILE = '.vona-test-owner';
|
|
8
|
+
|
|
9
|
+
const DATABASE_NAME_MAX_BYTES = 63;
|
|
10
|
+
const APP_NAME_MAX_BYTES = 13;
|
|
11
|
+
const HASH_LENGTH = 10;
|
|
12
|
+
const TIMESTAMP_LENGTH = 15;
|
|
13
|
+
|
|
14
|
+
export function getDatabaseTestPrefix(appName: string, scope: string): string {
|
|
15
|
+
const readablePrefix =
|
|
16
|
+
scope === 'share'
|
|
17
|
+
? `vona-test-${appName}-s-`
|
|
18
|
+
: `vona-test-${appName}-i-${scope.slice('isolate-'.length)}-`;
|
|
19
|
+
if (Buffer.byteLength(readablePrefix, 'utf8') + TIMESTAMP_LENGTH <= DATABASE_NAME_MAX_BYTES) {
|
|
20
|
+
return readablePrefix;
|
|
21
|
+
}
|
|
22
|
+
let appHead = '';
|
|
23
|
+
for (const char of appName) {
|
|
24
|
+
if (Buffer.byteLength(`${appHead}${char}`, 'utf8') > APP_NAME_MAX_BYTES) break;
|
|
25
|
+
appHead += char;
|
|
26
|
+
}
|
|
27
|
+
const scopeKind = scope === 'share' ? 's' : 'i';
|
|
28
|
+
const namespaceHash = createHash('sha256')
|
|
29
|
+
.update(`${appName}\0${scope}`)
|
|
30
|
+
.digest('base64url')
|
|
31
|
+
.slice(0, HASH_LENGTH);
|
|
32
|
+
return `vona-test-${appHead}-${scopeKind}-${namespaceHash}-`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function assertDisposableDatabaseName(databaseName: string, databasePrefix: string) {
|
|
36
|
+
if (
|
|
37
|
+
typeof databaseName !== 'string' ||
|
|
38
|
+
!databaseName.startsWith(databasePrefix) ||
|
|
39
|
+
!/^\d{8}-\d{6}$/.test(databaseName.slice(databasePrefix.length)) ||
|
|
40
|
+
Buffer.byteLength(databaseName, 'utf8') > DATABASE_NAME_MAX_BYTES
|
|
41
|
+
) {
|
|
42
|
+
throw new Error(`Database is outside the disposable namespace: ${databaseName}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function resolveTestRunId(
|
|
47
|
+
mode: string,
|
|
48
|
+
runId: string | undefined = process.env[TEST_RUN_ID_ENV],
|
|
49
|
+
) {
|
|
50
|
+
if (runId === undefined) return undefined;
|
|
51
|
+
const match = /^(\d{14})-[a-f0-9]{8}$/.exec(runId);
|
|
52
|
+
const timestamp = match?.[1];
|
|
53
|
+
const date = timestamp
|
|
54
|
+
? new Date(
|
|
55
|
+
`${timestamp.slice(0, 4)}-${timestamp.slice(4, 6)}-${timestamp.slice(6, 8)}T${timestamp.slice(8, 10)}:${timestamp.slice(10, 12)}:${timestamp.slice(12, 14)}Z`,
|
|
56
|
+
)
|
|
57
|
+
: undefined;
|
|
58
|
+
if (
|
|
59
|
+
mode !== 'test' ||
|
|
60
|
+
!timestamp ||
|
|
61
|
+
!date ||
|
|
62
|
+
Number.isNaN(date.getTime()) ||
|
|
63
|
+
date.toISOString().slice(0, 19).replace(/[-:T]/g, '') !== timestamp
|
|
64
|
+
) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`${TEST_RUN_ID_ENV} requires test mode and a UTC timestamp plus eight hex digits`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return runId;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function getTestAppName(runId: string) {
|
|
73
|
+
resolveTestRunId('test', runId);
|
|
74
|
+
return `cabtest${runId}`;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function assertTestAppIdentity(mode: string, runId: string | undefined, appName: string) {
|
|
78
|
+
const id = resolveTestRunId(mode, runId);
|
|
79
|
+
if (id && appName !== getTestAppName(id)) {
|
|
80
|
+
throw new Error('Isolated test APP_NAME does not match its run ID');
|
|
81
|
+
}
|
|
82
|
+
return id;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function getTestRunIdFromEnv(env: NodeJS.ProcessEnv) {
|
|
86
|
+
return resolveTestRunId(env.META_MODE, env[TEST_RUN_ID_ENV]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function assertTestRunOwner(root: string, runId: string) {
|
|
90
|
+
resolveTestRunId('test', runId);
|
|
91
|
+
let current = path.resolve(root);
|
|
92
|
+
while (true) {
|
|
93
|
+
try {
|
|
94
|
+
if (lstatSync(current).isSymbolicLink()) {
|
|
95
|
+
throw new Error(`Isolated test path traverses a symlink: ${current}`);
|
|
96
|
+
}
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;
|
|
99
|
+
}
|
|
100
|
+
const parent = path.dirname(current);
|
|
101
|
+
if (parent === current) break;
|
|
102
|
+
current = parent;
|
|
103
|
+
}
|
|
104
|
+
const marker = path.join(root, TEST_RUN_OWNER_FILE);
|
|
105
|
+
if (!fse.lstatSync(marker).isFile() || fse.readFileSync(marker, 'utf8') !== `${runId}\n`) {
|
|
106
|
+
throw new Error(`Isolated test directory has no matching owner: ${root}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function resolveVonaLocalPaths(
|
|
111
|
+
projectPath: string,
|
|
112
|
+
mode: string,
|
|
113
|
+
runId: string | undefined = process.env[TEST_RUN_ID_ENV],
|
|
114
|
+
) {
|
|
115
|
+
const id = resolveTestRunId(mode, runId);
|
|
116
|
+
const generatedDir = id ? `.vona-test-${id}` : '.vona';
|
|
117
|
+
const dataDir = id ? `.app-test-${id}` : '.app';
|
|
118
|
+
return {
|
|
119
|
+
runId: id,
|
|
120
|
+
generatedDir,
|
|
121
|
+
dataDir,
|
|
122
|
+
generatedRoot: path.join(projectPath, generatedDir),
|
|
123
|
+
dataRoot: path.join(projectPath, dataDir),
|
|
124
|
+
publicRoot: path.join(projectPath, dataDir, 'public'),
|
|
125
|
+
runtimeRoot: path.join(projectPath, dataDir, 'runtime'),
|
|
126
|
+
logsRoot: path.join(projectPath, dataDir, 'logs'),
|
|
127
|
+
sqliteRoot: path.join(projectPath, dataDir, 'sqlite3'),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -5,6 +5,7 @@ import type { BootstrapOptions } from '../../types/interface/bootstrap.ts';
|
|
|
5
5
|
import type { VonaConfigEnv } from '../../types/utils/env.ts';
|
|
6
6
|
|
|
7
7
|
import { VonaApplication } from '../core/application.ts';
|
|
8
|
+
import { assertTestAppIdentity } from '../core/testIsolation.ts';
|
|
8
9
|
import { jsxEnhance } from '../utils/jsx-enhance.ts';
|
|
9
10
|
import { prepareEnv } from '../utils/util.ts';
|
|
10
11
|
import { zodEnhance } from '../utils/zod-enhance.ts';
|
|
@@ -54,6 +55,7 @@ function __createApp({ modulesMeta, locales, config, env, AppMonkey }: Bootstrap
|
|
|
54
55
|
jsxEnhance();
|
|
55
56
|
// env
|
|
56
57
|
const env2 = prepareEnv(env);
|
|
58
|
+
assertTestAppIdentity(env2.META_MODE, env2.VONA_TEST_RUN_ID, env2.APP_NAME ?? '');
|
|
57
59
|
// appInfo
|
|
58
60
|
const appInfo = prepareAppInfo(env2);
|
|
59
61
|
// options
|
|
@@ -2,6 +2,8 @@ import type { VonaConfig, VonaConfigOptional } from '../../types/index.ts';
|
|
|
2
2
|
import type { VonaApplication } from '../core/application.ts';
|
|
3
3
|
|
|
4
4
|
import { EnumAppEvent } from '../../types/index.ts';
|
|
5
|
+
import { assertIsolatedTestConfig } from '../core/isolationGuard.ts';
|
|
6
|
+
import { registerTestClaimResourceInventory } from '../core/testClaim.ts';
|
|
5
7
|
import { ModuleLoader } from '../module/loader.ts';
|
|
6
8
|
import { deepExtend } from '../utils/util.ts';
|
|
7
9
|
|
|
@@ -65,6 +67,8 @@ export class Start {
|
|
|
65
67
|
// config
|
|
66
68
|
const appConfig = await __prepareConfig(app);
|
|
67
69
|
this.app.config = appConfig as VonaConfig;
|
|
70
|
+
assertIsolatedTestConfig(app);
|
|
71
|
+
await registerTestClaimResourceInventory(app);
|
|
68
72
|
this.app.keys = appConfig.server!.keys!;
|
|
69
73
|
this.app.proxy = appConfig.proxy!.enable!;
|
|
70
74
|
this.app.subdomainOffset = appConfig.server!.subdomainOffset!;
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
|
|
4
4
|
import type { VonaApplication } from '../core/application.ts';
|
|
5
5
|
|
|
6
|
+
import { resolveVonaLocalPaths } from '../core/testIsolation.ts';
|
|
6
7
|
import { pathToHref } from '../utils/util.ts';
|
|
7
8
|
|
|
8
9
|
export function useApp(): VonaApplication {
|
|
@@ -38,7 +39,10 @@ export async function createGeneralApp(
|
|
|
38
39
|
const testInstance = await import(pathToHref(testFile));
|
|
39
40
|
return await testInstance.appBootstrap;
|
|
40
41
|
} else {
|
|
41
|
-
const testFile = path.join(
|
|
42
|
+
const testFile = path.join(
|
|
43
|
+
resolveVonaLocalPaths(projectPath, process.env.META_MODE).generatedRoot,
|
|
44
|
+
'app.ts',
|
|
45
|
+
);
|
|
42
46
|
const testInstance = await import(pathToHref(testFile));
|
|
43
47
|
return await testInstance.createSingleApp();
|
|
44
48
|
}
|
|
@@ -42,6 +42,8 @@ export interface VonaApplicationOptions {
|
|
|
42
42
|
locales: TypeBootstrapOptionsLocales;
|
|
43
43
|
config: TypeBootstrapOptionsConfig;
|
|
44
44
|
env: VonaConfigEnv;
|
|
45
|
+
/** Internal cleanup-only source configuration resolution; never starts an application. */
|
|
46
|
+
configResolutionOnly?: boolean;
|
|
45
47
|
AppMonkey?: AppMonkeyConstructable;
|
|
46
48
|
}
|
|
47
49
|
|
package/vona/pnpm-lock.yaml
CHANGED
|
@@ -573,8 +573,8 @@ importers:
|
|
|
573
573
|
specifier: npm:@cabloy/zod@4.3.8
|
|
574
574
|
version: '@cabloy/zod@4.3.8'
|
|
575
575
|
zova:
|
|
576
|
-
specifier: ^5.1.
|
|
577
|
-
version: 5.1.
|
|
576
|
+
specifier: ^5.1.167
|
|
577
|
+
version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
578
578
|
zova-jsx:
|
|
579
579
|
specifier: ^1.1.92
|
|
580
580
|
version: 1.1.92(typescript@5.9.3)
|
|
@@ -606,8 +606,8 @@ importers:
|
|
|
606
606
|
specifier: ^5.1.37
|
|
607
607
|
version: 5.1.37(vue@3.5.43(typescript@5.9.3))
|
|
608
608
|
zova-module-a-openapi:
|
|
609
|
-
specifier: ^5.1.
|
|
610
|
-
version: 5.1.
|
|
609
|
+
specifier: ^5.1.55
|
|
610
|
+
version: 5.1.55
|
|
611
611
|
zova-module-a-pay:
|
|
612
612
|
specifier: ^5.0.9
|
|
613
613
|
version: 5.0.9
|
|
@@ -624,8 +624,8 @@ importers:
|
|
|
624
624
|
specifier: ^5.1.35
|
|
625
625
|
version: 5.1.35
|
|
626
626
|
zova-module-a-table:
|
|
627
|
-
specifier: ^5.1.
|
|
628
|
-
version: 5.1.
|
|
627
|
+
specifier: ^5.1.44
|
|
628
|
+
version: 5.1.44(vue@3.5.43(typescript@5.9.3))
|
|
629
629
|
zova-module-pay-mock:
|
|
630
630
|
specifier: ^5.0.5
|
|
631
631
|
version: 5.0.5
|
|
@@ -657,8 +657,8 @@ importers:
|
|
|
657
657
|
specifier: npm:@cabloy/zod@4.3.8
|
|
658
658
|
version: '@cabloy/zod@4.3.8'
|
|
659
659
|
zova:
|
|
660
|
-
specifier: ^5.1.
|
|
661
|
-
version: 5.1.
|
|
660
|
+
specifier: ^5.1.167
|
|
661
|
+
version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
662
662
|
zova-jsx:
|
|
663
663
|
specifier: ^1.1.92
|
|
664
664
|
version: 1.1.92(typescript@5.9.3)
|
|
@@ -690,8 +690,8 @@ importers:
|
|
|
690
690
|
specifier: ^5.1.37
|
|
691
691
|
version: 5.1.37(vue@3.5.43(typescript@5.9.3))
|
|
692
692
|
zova-module-a-openapi:
|
|
693
|
-
specifier: ^5.1.
|
|
694
|
-
version: 5.1.
|
|
693
|
+
specifier: ^5.1.55
|
|
694
|
+
version: 5.1.55
|
|
695
695
|
zova-module-a-pay:
|
|
696
696
|
specifier: ^5.0.9
|
|
697
697
|
version: 5.0.9
|
|
@@ -708,8 +708,8 @@ importers:
|
|
|
708
708
|
specifier: ^5.1.35
|
|
709
709
|
version: 5.1.35
|
|
710
710
|
zova-module-a-table:
|
|
711
|
-
specifier: ^5.1.
|
|
712
|
-
version: 5.1.
|
|
711
|
+
specifier: ^5.1.44
|
|
712
|
+
version: 5.1.44(vue@3.5.43(typescript@5.9.3))
|
|
713
713
|
zova-module-pay-mock:
|
|
714
714
|
specifier: ^5.0.5
|
|
715
715
|
version: 5.0.5
|
|
@@ -741,8 +741,8 @@ importers:
|
|
|
741
741
|
specifier: npm:@cabloy/zod@4.3.8
|
|
742
742
|
version: '@cabloy/zod@4.3.8'
|
|
743
743
|
zova:
|
|
744
|
-
specifier: ^5.1.
|
|
745
|
-
version: 5.1.
|
|
744
|
+
specifier: ^5.1.167
|
|
745
|
+
version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
746
746
|
zova-jsx:
|
|
747
747
|
specifier: ^1.1.92
|
|
748
748
|
version: 1.1.92(typescript@5.9.3)
|
|
@@ -774,8 +774,8 @@ importers:
|
|
|
774
774
|
specifier: ^5.1.37
|
|
775
775
|
version: 5.1.37(vue@3.5.43(typescript@5.9.3))
|
|
776
776
|
zova-module-a-openapi:
|
|
777
|
-
specifier: ^5.1.
|
|
778
|
-
version: 5.1.
|
|
777
|
+
specifier: ^5.1.55
|
|
778
|
+
version: 5.1.55
|
|
779
779
|
zova-module-a-pay:
|
|
780
780
|
specifier: ^5.0.9
|
|
781
781
|
version: 5.0.9
|
|
@@ -792,8 +792,8 @@ importers:
|
|
|
792
792
|
specifier: ^5.1.35
|
|
793
793
|
version: 5.1.35
|
|
794
794
|
zova-module-a-table:
|
|
795
|
-
specifier: ^5.1.
|
|
796
|
-
version: 5.1.
|
|
795
|
+
specifier: ^5.1.44
|
|
796
|
+
version: 5.1.44(vue@3.5.43(typescript@5.9.3))
|
|
797
797
|
zova-module-pay-mock:
|
|
798
798
|
specifier: ^5.0.5
|
|
799
799
|
version: 5.0.5
|
|
@@ -825,8 +825,8 @@ importers:
|
|
|
825
825
|
specifier: npm:@cabloy/zod@4.3.8
|
|
826
826
|
version: '@cabloy/zod@4.3.8'
|
|
827
827
|
zova:
|
|
828
|
-
specifier: ^5.1.
|
|
829
|
-
version: 5.1.
|
|
828
|
+
specifier: ^5.1.167
|
|
829
|
+
version: 5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
830
830
|
zova-jsx:
|
|
831
831
|
specifier: ^1.1.92
|
|
832
832
|
version: 1.1.92(typescript@5.9.3)
|
|
@@ -858,8 +858,8 @@ importers:
|
|
|
858
858
|
specifier: ^5.1.37
|
|
859
859
|
version: 5.1.37(vue@3.5.43(typescript@5.9.3))
|
|
860
860
|
zova-module-a-openapi:
|
|
861
|
-
specifier: ^5.1.
|
|
862
|
-
version: 5.1.
|
|
861
|
+
specifier: ^5.1.55
|
|
862
|
+
version: 5.1.55
|
|
863
863
|
zova-module-a-pay:
|
|
864
864
|
specifier: ^5.0.9
|
|
865
865
|
version: 5.0.9
|
|
@@ -876,8 +876,8 @@ importers:
|
|
|
876
876
|
specifier: ^5.1.35
|
|
877
877
|
version: 5.1.35
|
|
878
878
|
zova-module-a-table:
|
|
879
|
-
specifier: ^5.1.
|
|
880
|
-
version: 5.1.
|
|
879
|
+
specifier: ^5.1.44
|
|
880
|
+
version: 5.1.44(vue@3.5.43(typescript@5.9.3))
|
|
881
881
|
zova-module-pay-mock:
|
|
882
882
|
specifier: ^5.0.5
|
|
883
883
|
version: 5.0.5
|
|
@@ -1652,7 +1652,7 @@ importers:
|
|
|
1652
1652
|
specifier: ^5.0.3
|
|
1653
1653
|
version: link:modules/a-markdown
|
|
1654
1654
|
vona-module-a-rbac:
|
|
1655
|
-
specifier: ^5.0.
|
|
1655
|
+
specifier: ^5.0.9
|
|
1656
1656
|
version: link:modules/a-rbac
|
|
1657
1657
|
vona-module-a-socket:
|
|
1658
1658
|
specifier: workspace:^
|
|
@@ -8938,8 +8938,8 @@ packages:
|
|
|
8938
8938
|
zova-module-a-model@5.1.37:
|
|
8939
8939
|
resolution: {integrity: sha512-Ipas8Lpsi9Jcgu3AbzajgqcBffmg1GeIBOu4UtOyR5fbRDvlxYWXx45rA52oB/zgoC+QvhUVzY36fnNfTJiywg==}
|
|
8940
8940
|
|
|
8941
|
-
zova-module-a-openapi@5.1.
|
|
8942
|
-
resolution: {integrity: sha512
|
|
8941
|
+
zova-module-a-openapi@5.1.55:
|
|
8942
|
+
resolution: {integrity: sha512-jdbUN4QEAQZvx+EmwaDfIa0Xy5MoNOVYLdLnEl+LbANc6COxkGGSyroFBRXG5S/Av0YWIBUbgahuEpFdL+RYjw==}
|
|
8943
8943
|
|
|
8944
8944
|
zova-module-a-pay@5.0.9:
|
|
8945
8945
|
resolution: {integrity: sha512-Chl6EKp30HBOGFCJXbla2/lS19WhzQyTZwgYmsL3nnG9Vt2TeUlb82vsYCVuDcy0cgmxVaWjPF7dzKL/r3Pfng==}
|
|
@@ -8965,8 +8965,8 @@ packages:
|
|
|
8965
8965
|
zova-module-a-style@5.1.35:
|
|
8966
8966
|
resolution: {integrity: sha512-i73I3wFvdQonj3l4fkovkKBZwSK4s6D4vL3AVfVvFJ4eIboKH2yw0hCILKRzLoESNQ0T+lNS6ozeimvtA4/6DQ==}
|
|
8967
8967
|
|
|
8968
|
-
zova-module-a-table@5.1.
|
|
8969
|
-
resolution: {integrity: sha512-
|
|
8968
|
+
zova-module-a-table@5.1.44:
|
|
8969
|
+
resolution: {integrity: sha512-wc9tABJ20tVX2RL/9xTfgHgdDnvN9UoJQm8k25Ay/72r9K5WfoRk4dHfgjEQXIgOVyWWXTWkI1SGcvUkqC3JbA==}
|
|
8970
8970
|
|
|
8971
8971
|
zova-module-a-zod@5.1.37:
|
|
8972
8972
|
resolution: {integrity: sha512-rXHN9rKbum9w3gDSnC/pIusG2d2FGJOcIauf8jrbT96f+Olk4Q3iV3t2V92mxiLCh9kMvBJPfcOgJFW7pRB5Fw==}
|
|
@@ -8980,11 +8980,11 @@ packages:
|
|
|
8980
8980
|
zova-module-rest-resource@5.1.55:
|
|
8981
8981
|
resolution: {integrity: sha512-Kk3oJIcxM5EbeTLl+ucJSeI2kT0We8YilXBaX8Z7QWCbZ0fHoQDy/Ac4YsVSWIXUrC2SQ267+nMl3sHXnE9G0Q==}
|
|
8982
8982
|
|
|
8983
|
-
zova-suite-a-zova@5.1.
|
|
8984
|
-
resolution: {integrity: sha512-
|
|
8983
|
+
zova-suite-a-zova@5.1.166:
|
|
8984
|
+
resolution: {integrity: sha512-2mmuMDS4uEvq4x9p/StuBb8E+9Czg7G/S6E9IF2SdwBGmXB6dtcog1rNquvUyNLOujw2UNn2uUyuIY0WPRUc0g==}
|
|
8985
8985
|
|
|
8986
|
-
zova@5.1.
|
|
8987
|
-
resolution: {integrity: sha512-
|
|
8986
|
+
zova@5.1.167:
|
|
8987
|
+
resolution: {integrity: sha512-A0vfiT2eXuKbKW1GxlZNnsZPuPvS/mAHfoaiBsN5Pf4GYOKE/7R9fJIbl9YQzNWkV3LP3vECygqBHg9q2qr9Bw==}
|
|
8988
8988
|
|
|
8989
8989
|
zwitch@1.0.5:
|
|
8990
8990
|
resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==}
|
|
@@ -15158,7 +15158,7 @@ snapshots:
|
|
|
15158
15158
|
- '@vue/composition-api'
|
|
15159
15159
|
- vue
|
|
15160
15160
|
|
|
15161
|
-
zova-module-a-openapi@5.1.
|
|
15161
|
+
zova-module-a-openapi@5.1.55:
|
|
15162
15162
|
dependencies:
|
|
15163
15163
|
'@cabloy/json-schema-to-zod': 2.6.5
|
|
15164
15164
|
openapi3-ts: 4.6.1
|
|
@@ -15191,7 +15191,7 @@ snapshots:
|
|
|
15191
15191
|
csx: 10.0.2
|
|
15192
15192
|
typestyle: 2.4.0
|
|
15193
15193
|
|
|
15194
|
-
zova-module-a-table@5.1.
|
|
15194
|
+
zova-module-a-table@5.1.44(vue@3.5.43(typescript@5.9.3)):
|
|
15195
15195
|
dependencies:
|
|
15196
15196
|
'@tanstack/table-core': 8.21.3
|
|
15197
15197
|
'@tanstack/vue-table': 8.21.3(vue@3.5.43(typescript@5.9.3))
|
|
@@ -15225,7 +15225,7 @@ snapshots:
|
|
|
15225
15225
|
|
|
15226
15226
|
zova-module-rest-resource@5.1.55: {}
|
|
15227
15227
|
|
|
15228
|
-
zova-suite-a-zova@5.1.
|
|
15228
|
+
zova-suite-a-zova@5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
|
|
15229
15229
|
dependencies:
|
|
15230
15230
|
zova-module-a-api: 5.1.22
|
|
15231
15231
|
zova-module-a-app: 5.1.26
|
|
@@ -15240,7 +15240,7 @@ snapshots:
|
|
|
15240
15240
|
zova-module-a-logger: 5.1.28
|
|
15241
15241
|
zova-module-a-meta: 5.1.22
|
|
15242
15242
|
zova-module-a-model: 5.1.37(vue@3.5.43(typescript@5.9.3))
|
|
15243
|
-
zova-module-a-openapi: 5.1.
|
|
15243
|
+
zova-module-a-openapi: 5.1.55
|
|
15244
15244
|
zova-module-a-router: 5.1.41
|
|
15245
15245
|
zova-module-a-routerstack: 5.1.29
|
|
15246
15246
|
zova-module-a-routertabs: 5.1.34
|
|
@@ -15248,7 +15248,7 @@ snapshots:
|
|
|
15248
15248
|
zova-module-a-ssrhmr: 5.1.23
|
|
15249
15249
|
zova-module-a-ssrserver: 5.1.26
|
|
15250
15250
|
zova-module-a-style: 5.1.35
|
|
15251
|
-
zova-module-a-table: 5.1.
|
|
15251
|
+
zova-module-a-table: 5.1.44(vue@3.5.43(typescript@5.9.3))
|
|
15252
15252
|
zova-module-a-zod: 5.1.37
|
|
15253
15253
|
zova-module-a-zova: 5.1.108(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
15254
15254
|
transitivePeerDependencies:
|
|
@@ -15258,10 +15258,10 @@ snapshots:
|
|
|
15258
15258
|
- typescript
|
|
15259
15259
|
- vue
|
|
15260
15260
|
|
|
15261
|
-
zova@5.1.
|
|
15261
|
+
zova@5.1.167(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3)):
|
|
15262
15262
|
dependencies:
|
|
15263
15263
|
zova-core: 5.1.92(patch_hash=144450bd7a567a6067e5857c0cf4c780981b7e90bc48745c09e1696a9b6f1b97)(typescript@5.9.3)
|
|
15264
|
-
zova-suite-a-zova: 5.1.
|
|
15264
|
+
zova-suite-a-zova: 5.1.166(typescript@5.9.3)(vue@3.5.43(typescript@5.9.3))
|
|
15265
15265
|
transitivePeerDependencies:
|
|
15266
15266
|
- '@vue/composition-api'
|
|
15267
15267
|
- debug
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import type { IMetaOptionsIndex } from 'vona-module-a-index';
|
|
2
2
|
|
|
3
|
+
import { DateTime } from 'luxon';
|
|
3
4
|
import assert from 'node:assert/strict';
|
|
4
5
|
import { randomUUID } from 'node:crypto';
|
|
5
|
-
import {
|
|
6
|
-
import { tmpdir } from 'node:os';
|
|
6
|
+
import { lstat, open, rm } from 'node:fs/promises';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import { describe, it } from 'node:test';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
appResource,
|
|
11
|
+
assertDisposableDatabaseName,
|
|
12
|
+
assertIsolatedTestPath,
|
|
13
|
+
assertTestRunOwner,
|
|
14
|
+
getDatabaseTestPrefix,
|
|
15
|
+
registerTestClaimDatabaseCreation,
|
|
16
|
+
resolveVonaLocalPaths,
|
|
17
|
+
} from 'vona';
|
|
10
18
|
import { app } from 'vona-mock';
|
|
11
19
|
import { ServiceDatabaseAsyncLocalStorage, ServiceDatabaseClient } from 'vona-module-a-orm';
|
|
12
20
|
|
|
@@ -24,6 +32,56 @@ const expectedIndexes = {
|
|
|
24
32
|
],
|
|
25
33
|
};
|
|
26
34
|
|
|
35
|
+
const attemptedCopyNames = new Set<string>();
|
|
36
|
+
|
|
37
|
+
async function allocateOwnedSqliteCopy(source: ServiceDatabaseClient) {
|
|
38
|
+
const runId = app.meta.env.VONA_TEST_RUN_ID;
|
|
39
|
+
assert.ok(runId, 'the isolated SQLite copy requires a test run ID');
|
|
40
|
+
const paths = resolveVonaLocalPaths(app.projectPath, 'test', runId);
|
|
41
|
+
assertTestRunOwner(paths.dataRoot, runId);
|
|
42
|
+
const prefix = getDatabaseTestPrefix(app.name, 'share');
|
|
43
|
+
|
|
44
|
+
for (let offset = 0; offset < 3600; offset++) {
|
|
45
|
+
const timestamp = DateTime.now().plus({ seconds: offset }).toFormat('yyyyMMdd-HHmmss');
|
|
46
|
+
const databaseName = `${prefix}${timestamp}`;
|
|
47
|
+
assertDisposableDatabaseName(databaseName, prefix);
|
|
48
|
+
const filename = path.join(paths.sqliteRoot, `${databaseName}.db`);
|
|
49
|
+
if (attemptedCopyNames.has(filename)) continue;
|
|
50
|
+
const reservation = `${filename}.lock`;
|
|
51
|
+
assertIsolatedTestPath(filename, path.join(paths.sqliteRoot, path.basename(filename)));
|
|
52
|
+
assertIsolatedTestPath(reservation, path.join(paths.sqliteRoot, path.basename(reservation)));
|
|
53
|
+
try {
|
|
54
|
+
const reservationHandle = await open(reservation, 'wx');
|
|
55
|
+
await reservationHandle.close();
|
|
56
|
+
try {
|
|
57
|
+
const exists = await lstat(filename).then(
|
|
58
|
+
() => true,
|
|
59
|
+
error => {
|
|
60
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false;
|
|
61
|
+
throw error;
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
if (exists) {
|
|
65
|
+
await rm(reservation);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
attemptedCopyNames.add(filename);
|
|
69
|
+
await registerTestClaimDatabaseCreation(app, source.clientConfig, databaseName, 'intent');
|
|
70
|
+
const databaseHandle = await open(filename, 'wx');
|
|
71
|
+
await databaseHandle.close();
|
|
72
|
+
await rm(filename);
|
|
73
|
+
return { filename, paths, reservation };
|
|
74
|
+
} catch (error) {
|
|
75
|
+
await rm(reservation, { force: true });
|
|
76
|
+
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
throw new Error('Unable to allocate an owned SQLite copy name');
|
|
83
|
+
}
|
|
84
|
+
|
|
27
85
|
describe('paymentIndexes.test.ts', { concurrency: false }, () => {
|
|
28
86
|
it('registers all payment indexes without overwriting table keys', () => {
|
|
29
87
|
const options = appResource.getBean('commerce-payment.meta.index')
|
|
@@ -85,12 +143,17 @@ describe('paymentIndexes.test.ts', { concurrency: false }, () => {
|
|
|
85
143
|
t.skip('SQLite-only independent database copy');
|
|
86
144
|
return;
|
|
87
145
|
}
|
|
88
|
-
const directory = await mkdtemp(path.join(tmpdir(), 'commerce-index-recovery-'));
|
|
89
|
-
const filename = path.join(directory, 'existing.db');
|
|
90
146
|
const source = app.bean.database.current;
|
|
147
|
+
const { filename, paths, reservation } = await allocateOwnedSqliteCopy(source.client);
|
|
91
148
|
let client: ServiceDatabaseClient | undefined;
|
|
92
149
|
try {
|
|
93
150
|
await source.connection.raw('VACUUM main INTO ?', [filename]);
|
|
151
|
+
await registerTestClaimDatabaseCreation(
|
|
152
|
+
app,
|
|
153
|
+
source.client.clientConfig,
|
|
154
|
+
path.basename(filename, '.db'),
|
|
155
|
+
'created',
|
|
156
|
+
);
|
|
94
157
|
const selector = `index-recovery-${randomUUID()}`;
|
|
95
158
|
client = app.bean._newBean(ServiceDatabaseClient, selector, {
|
|
96
159
|
client: 'better-sqlite3',
|
|
@@ -154,11 +217,11 @@ describe('paymentIndexes.test.ts', { concurrency: false }, () => {
|
|
|
154
217
|
}
|
|
155
218
|
});
|
|
156
219
|
} finally {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
220
|
+
if (client) await client.connection.destroy();
|
|
221
|
+
assertTestRunOwner(paths.dataRoot, paths.runId!);
|
|
222
|
+
assertIsolatedTestPath(filename, filename);
|
|
223
|
+
await source.connection.schema.dropDatabase(filename);
|
|
224
|
+
await rm(reservation, { force: true });
|
|
162
225
|
}
|
|
163
226
|
});
|
|
164
227
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vona-suite-a-cabloy",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.61",
|
|
4
4
|
"gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"vona-module-a-cabloy": "workspace:^",
|
|
11
11
|
"vona-module-a-layoutprofile": "^5.0.2",
|
|
12
12
|
"vona-module-a-markdown": "^5.0.3",
|
|
13
|
-
"vona-module-a-rbac": "^5.0.
|
|
13
|
+
"vona-module-a-rbac": "^5.0.10",
|
|
14
14
|
"vona-module-a-socket": "workspace:^",
|
|
15
15
|
"vona-module-a-ssr": "workspace:^",
|
|
16
16
|
"vona-module-a-ssrhmr": "workspace:^"
|
|
@@ -8,6 +8,8 @@ import StdSerializers from 'pino-std-serializers';
|
|
|
8
8
|
import { BeanBase } from 'vona';
|
|
9
9
|
import { MiddlewareSystem } from 'vona-module-a-aspect';
|
|
10
10
|
|
|
11
|
+
import { redactIsolatedReadyHeader } from '../lib/redactIsolatedReadyHeader.ts';
|
|
12
|
+
|
|
11
13
|
export interface IMiddlewareSystemOptionsHttpLog extends IDecoratorMiddlewareSystemOptions {}
|
|
12
14
|
|
|
13
15
|
@MiddlewareSystem<IMiddlewareSystemOptionsHttpLog>()
|
|
@@ -16,15 +18,27 @@ export class MiddlewareSystemHttpLog extends BeanBase implements IMiddlewareSyst
|
|
|
16
18
|
const ctx = this.ctx;
|
|
17
19
|
// start
|
|
18
20
|
const req = StdSerializers.req(ctx.req);
|
|
21
|
+
req.headers = redactIsolatedReadyHeader(
|
|
22
|
+
req.headers,
|
|
23
|
+
ctx.path,
|
|
24
|
+
this.app.meta.env.VONA_TEST_RUN_ID,
|
|
25
|
+
'x-vona-test-challenge',
|
|
26
|
+
);
|
|
19
27
|
this.$loggerChild('req').http(() => JSON.stringify(req));
|
|
20
28
|
const profiler = this.$loggerChild('res').startTimer();
|
|
21
29
|
// next
|
|
22
30
|
await next();
|
|
23
31
|
// end
|
|
32
|
+
const headers = redactIsolatedReadyHeader(
|
|
33
|
+
ctx.res.getHeaders(),
|
|
34
|
+
ctx.path,
|
|
35
|
+
this.app.meta.env.VONA_TEST_RUN_ID,
|
|
36
|
+
'x-vona-test-proof',
|
|
37
|
+
);
|
|
24
38
|
const res = {
|
|
25
39
|
url: ctx.req.url,
|
|
26
40
|
statusCode: ctx.res.statusCode,
|
|
27
|
-
headers
|
|
41
|
+
headers,
|
|
28
42
|
};
|
|
29
43
|
profiler.done({ level: 'http', message: JSON.stringify(res) });
|
|
30
44
|
}
|
package/vona/src/suite-vendor/a-vona/modules/a-logger/src/lib/redactIsolatedReadyHeader.test.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { test } from 'node:test';
|
|
3
|
+
|
|
4
|
+
import { redactIsolatedReadyHeader } from './redactIsolatedReadyHeader.ts';
|
|
5
|
+
|
|
6
|
+
test('redacts isolated readiness challenge and proof without changing live headers', () => {
|
|
7
|
+
const runId = '20261014010203-a1b2c3d4';
|
|
8
|
+
const req = { 'x-vona-test-challenge': 'challenge-value', 'accept': 'application/json' };
|
|
9
|
+
const res = { 'x-vona-test-proof': 'proof-value', 'content-type': 'application/json' };
|
|
10
|
+
const loggedReq = redactIsolatedReadyHeader(req, '/health/ready', runId, 'x-vona-test-challenge');
|
|
11
|
+
const loggedRes = redactIsolatedReadyHeader(res, '/health/ready', runId, 'x-vona-test-proof');
|
|
12
|
+
|
|
13
|
+
assert.equal(JSON.stringify(loggedReq).includes('challenge-value'), false);
|
|
14
|
+
assert.equal(JSON.stringify(loggedRes).includes('proof-value'), false);
|
|
15
|
+
assert.equal(loggedReq.accept, 'application/json');
|
|
16
|
+
assert.equal(loggedRes['content-type'], 'application/json');
|
|
17
|
+
assert.equal(req['x-vona-test-challenge'], 'challenge-value');
|
|
18
|
+
assert.equal(res['x-vona-test-proof'], 'proof-value');
|
|
19
|
+
assert.equal(redactIsolatedReadyHeader(req, '/health/live', runId, 'x-vona-test-challenge'), req);
|
|
20
|
+
assert.equal(
|
|
21
|
+
redactIsolatedReadyHeader(req, '/health/ready', undefined, 'x-vona-test-challenge'),
|
|
22
|
+
req,
|
|
23
|
+
);
|
|
24
|
+
});
|