callman-core 1.9.1 → 1.11.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.
- package/ai-packs/feature-policy.md +26 -0
- package/ai-packs/pm-api.md +213 -0
- package/ai-packs/sandbox-globals.md +20 -0
- package/ai-packs/templating.md +104 -0
- package/dist/host/connections.d.ts +67 -0
- package/dist/host/connections.d.ts.map +1 -0
- package/dist/host/connections.js +156 -0
- package/dist/host/connections.js.map +1 -0
- package/dist/host/db/mongoAdapter.d.ts +7 -0
- package/dist/host/db/mongoAdapter.d.ts.map +1 -0
- package/dist/host/db/mongoAdapter.js +426 -0
- package/dist/host/db/mongoAdapter.js.map +1 -0
- package/dist/host/db/mysqlAdapter.d.ts +7 -0
- package/dist/host/db/mysqlAdapter.d.ts.map +1 -0
- package/dist/host/db/mysqlAdapter.js +68 -0
- package/dist/host/db/mysqlAdapter.js.map +1 -0
- package/dist/host/db/oracleAdapter.d.ts +7 -0
- package/dist/host/db/oracleAdapter.d.ts.map +1 -0
- package/dist/host/db/oracleAdapter.js +142 -0
- package/dist/host/db/oracleAdapter.js.map +1 -0
- package/dist/host/db/oracleConnectString.d.ts +10 -0
- package/dist/host/db/oracleConnectString.d.ts.map +1 -0
- package/dist/host/db/oracleConnectString.js +58 -0
- package/dist/host/db/oracleConnectString.js.map +1 -0
- package/dist/host/db/postgresAdapter.d.ts +7 -0
- package/dist/host/db/postgresAdapter.d.ts.map +1 -0
- package/dist/host/db/postgresAdapter.js +67 -0
- package/dist/host/db/postgresAdapter.js.map +1 -0
- package/dist/host/db/queryExecutor.d.ts +3 -0
- package/dist/host/db/queryExecutor.d.ts.map +1 -0
- package/dist/host/db/queryExecutor.js +97 -0
- package/dist/host/db/queryExecutor.js.map +1 -0
- package/dist/host/db/sqlNormalize.d.ts +3 -0
- package/dist/host/db/sqlNormalize.d.ts.map +1 -0
- package/dist/host/db/sqlNormalize.js +29 -0
- package/dist/host/db/sqlNormalize.js.map +1 -0
- package/dist/host/db/templateResolver.d.ts +3 -0
- package/dist/host/db/templateResolver.d.ts.map +1 -0
- package/dist/host/db/templateResolver.js +77 -0
- package/dist/host/db/templateResolver.js.map +1 -0
- package/dist/host/db/types.d.ts +59 -0
- package/dist/host/db/types.d.ts.map +1 -0
- package/dist/host/db/types.js +6 -0
- package/dist/host/db/types.js.map +1 -0
- package/dist/host/index.d.ts +6 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +7 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/lazy.d.ts +3 -0
- package/dist/host/lazy.d.ts.map +1 -0
- package/dist/host/lazy.js +31 -0
- package/dist/host/lazy.js.map +1 -0
- package/dist/host/redis/redisService.d.ts +9 -0
- package/dist/host/redis/redisService.d.ts.map +1 -0
- package/dist/host/redis/redisService.js +264 -0
- package/dist/host/redis/redisService.js.map +1 -0
- package/dist/host/redis/types.d.ts +44 -0
- package/dist/host/redis/types.d.ts.map +1 -0
- package/dist/host/redis/types.js +4 -0
- package/dist/host/redis/types.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/runner/requestRunner.d.ts.map +1 -1
- package/dist/runner/requestRunner.js +120 -0
- package/dist/runner/requestRunner.js.map +1 -1
- package/dist/runner/runCollection.d.ts +1 -1
- package/dist/runner/runCollection.d.ts.map +1 -1
- package/dist/runner/runCollection.js +3 -1
- package/dist/runner/runCollection.js.map +1 -1
- package/dist/scenario-runner/adapters/script-executor.js +3 -3
- package/dist/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist/script/features/log.d.ts.map +1 -1
- package/dist/script/features/log.js +23 -4
- package/dist/script/features/log.js.map +1 -1
- package/dist/script/isolated-runner.d.ts +11 -0
- package/dist/script/isolated-runner.d.ts.map +1 -0
- package/dist/script/isolated-runner.js +172 -0
- package/dist/script/isolated-runner.js.map +1 -0
- package/dist/script/legacy.d.ts.map +1 -1
- package/dist/script/legacy.js +8 -0
- package/dist/script/legacy.js.map +1 -1
- package/dist/script/pm-api-metadata.d.ts +19 -0
- package/dist/script/pm-api-metadata.d.ts.map +1 -0
- package/dist/script/pm-api-metadata.js +264 -0
- package/dist/script/pm-api-metadata.js.map +1 -0
- package/dist/script/scope.d.ts +2 -0
- package/dist/script/scope.d.ts.map +1 -1
- package/dist/script/scope.js +4 -0
- package/dist/script/scope.js.map +1 -1
- package/dist/script/worker-entry.d.ts +2 -0
- package/dist/script/worker-entry.d.ts.map +1 -0
- package/dist/script/worker-entry.js +79 -0
- package/dist/script/worker-entry.js.map +1 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist-cjs/host/connections.js +164 -0
- package/dist-cjs/host/connections.js.map +1 -0
- package/dist-cjs/host/db/mongoAdapter.js +431 -0
- package/dist-cjs/host/db/mongoAdapter.js.map +1 -0
- package/dist-cjs/host/db/mysqlAdapter.js +73 -0
- package/dist-cjs/host/db/mysqlAdapter.js.map +1 -0
- package/dist-cjs/host/db/oracleAdapter.js +147 -0
- package/dist-cjs/host/db/oracleAdapter.js.map +1 -0
- package/dist-cjs/host/db/oracleConnectString.js +63 -0
- package/dist-cjs/host/db/oracleConnectString.js.map +1 -0
- package/dist-cjs/host/db/postgresAdapter.js +72 -0
- package/dist-cjs/host/db/postgresAdapter.js.map +1 -0
- package/dist-cjs/host/db/queryExecutor.js +101 -0
- package/dist-cjs/host/db/queryExecutor.js.map +1 -0
- package/dist-cjs/host/db/sqlNormalize.js +33 -0
- package/dist-cjs/host/db/sqlNormalize.js.map +1 -0
- package/dist-cjs/host/db/templateResolver.js +81 -0
- package/dist-cjs/host/db/templateResolver.js.map +1 -0
- package/dist-cjs/host/db/types.js +7 -0
- package/dist-cjs/host/db/types.js.map +1 -0
- package/dist-cjs/host/index.js +17 -0
- package/dist-cjs/host/index.js.map +1 -0
- package/dist-cjs/host/lazy.js +69 -0
- package/dist-cjs/host/lazy.js.map +1 -0
- package/dist-cjs/host/redis/redisService.js +268 -0
- package/dist-cjs/host/redis/redisService.js.map +1 -0
- package/dist-cjs/host/redis/types.js +5 -0
- package/dist-cjs/host/redis/types.js.map +1 -0
- package/dist-cjs/index.js +10 -1
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/runner/requestRunner.js +120 -0
- package/dist-cjs/runner/requestRunner.js.map +1 -1
- package/dist-cjs/runner/runCollection.js +3 -1
- package/dist-cjs/runner/runCollection.js.map +1 -1
- package/dist-cjs/scenario-runner/adapters/script-executor.js +3 -3
- package/dist-cjs/scenario-runner/adapters/script-executor.js.map +1 -1
- package/dist-cjs/script/features/log.js +23 -4
- package/dist-cjs/script/features/log.js.map +1 -1
- package/dist-cjs/script/isolated-runner.js +209 -0
- package/dist-cjs/script/isolated-runner.js.map +1 -0
- package/dist-cjs/script/legacy.js +8 -0
- package/dist-cjs/script/legacy.js.map +1 -1
- package/dist-cjs/script/pm-api-metadata.js +267 -0
- package/dist-cjs/script/pm-api-metadata.js.map +1 -0
- package/dist-cjs/script/scope.js +5 -1
- package/dist-cjs/script/scope.js.map +1 -1
- package/dist-cjs/script/worker-entry.js +81 -0
- package/dist-cjs/script/worker-entry.js.map +1 -0
- package/package.json +15 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/host/db/types.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,6EAA6E;AAC7E,8EAA8E;AAC9E,oBAAoB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { buildDbExecuteCapability, runConfiguredDbQuery, runRedisCommandsForPhase, buildRedisValueCache, buildRedisCapability, type ConnectionRuntime, type ConnectionRuntimeMap, type DbConnectionRuntime, type RedisConnectionRuntime, type DbNodeConfig, type RequestDatabaseRuntimeConfig, type RequestRedisRuntimeConfig, type ScriptTemplateContext, } from "./connections.js";
|
|
2
|
+
export { executeQuery } from "./db/queryExecutor.js";
|
|
3
|
+
export { type DbConnection, type DbConnectionInput, type DbConnectionType, type DbConnectionMode, type DbQueryExecutionResult, type DbQueryPhase, } from "./db/types.js";
|
|
4
|
+
export { executeRedisCommands } from "./redis/redisService.js";
|
|
5
|
+
export { type RedisCommandExecutionResult, type RedisCommandPhase, type RequestRedisResult, } from "./redis/types.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,GAC3B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Host execution layer — local DB / Redis drivers + the glue that turns
|
|
2
|
+
// resolved connection runtimes into script capabilities. Lets the collection
|
|
3
|
+
// runner execute `pm.db.*` and `pm.redis` without an external host process.
|
|
4
|
+
export { buildDbExecuteCapability, runConfiguredDbQuery, runRedisCommandsForPhase, buildRedisValueCache, buildRedisCapability, } from "./connections.js";
|
|
5
|
+
export { executeQuery } from "./db/queryExecutor.js";
|
|
6
|
+
export { executeRedisCommands } from "./redis/redisService.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,6EAA6E;AAC7E,4EAA4E;AAE5E,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,GASrB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAUrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../../src/host/lazy.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,KAAG,OAAO,CAAC,GAAG,CAQjE,CAAC;AAIF,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,KAChB,OAAO,CAAC,GAAG,GAAG,IAAI,CAMpB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Lazy loader for OPTIONAL native driver packages (mongodb, pg, mysql2,
|
|
2
|
+
// oracledb, ioredis, bson). callman-core stays runtime-agnostic: these are
|
|
3
|
+
// declared as `optionalDependencies` and only loaded the first time a query
|
|
4
|
+
// that needs them runs. Hosts that never touch a given database never pay the
|
|
5
|
+
// native-install cost.
|
|
6
|
+
//
|
|
7
|
+
// The specifier is passed as a *variable* on purpose — that stops the
|
|
8
|
+
// TypeScript compiler from statically resolving (and erroring on) packages
|
|
9
|
+
// that may not be installed, while Node's runtime resolution still finds the
|
|
10
|
+
// real module by walking up `node_modules`.
|
|
11
|
+
const moduleCache = new Map();
|
|
12
|
+
export const loadOptionalModule = (specifier) => {
|
|
13
|
+
const cached = moduleCache.get(specifier);
|
|
14
|
+
if (cached) {
|
|
15
|
+
return cached;
|
|
16
|
+
}
|
|
17
|
+
const loading = import(specifier);
|
|
18
|
+
moduleCache.set(specifier, loading);
|
|
19
|
+
return loading;
|
|
20
|
+
};
|
|
21
|
+
// Like `loadOptionalModule` but resolves to `null` instead of throwing when the
|
|
22
|
+
// module is absent. Used for soft dependencies (e.g. `bson` for Decimal128).
|
|
23
|
+
export const loadOptionalModuleOrNull = async (specifier) => {
|
|
24
|
+
try {
|
|
25
|
+
return await loadOptionalModule(specifier);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=lazy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy.js","sourceRoot":"","sources":["../../src/host/lazy.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,uBAAuB;AACvB,EAAE;AACF,sEAAsE;AACtE,2EAA2E;AAC3E,6EAA6E;AAC7E,4CAA4C;AAE5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAA4B,CAAC;AAExD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAiB,EAAgB,EAAE;IACpE,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAsB,CAAC;IAChC,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,OAAuB,CAAC;AACjC,CAAC,CAAC;AAEF,gFAAgF;AAChF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC3C,SAAiB,EACI,EAAE;IACvB,IAAI,CAAC;QACH,OAAO,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RedisCommandExecutionResult, RedisCommandPhase, RedisConnectionInput, RedisTemplateContext } from "./types.js";
|
|
2
|
+
export declare const executeRedisCommands: ({ connectionId, connection: connectionInput, commands, phase, context, }: {
|
|
3
|
+
connectionId: string;
|
|
4
|
+
connection?: RedisConnectionInput;
|
|
5
|
+
commands: string[];
|
|
6
|
+
phase: RedisCommandPhase;
|
|
7
|
+
context?: RedisTemplateContext;
|
|
8
|
+
}) => Promise<RedisCommandExecutionResult[]>;
|
|
9
|
+
//# sourceMappingURL=redisService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redisService.d.ts","sourceRoot":"","sources":["../../../src/host/redis/redisService.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,2BAA2B,EAC3B,iBAAiB,EAEjB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAgUpB,eAAO,MAAM,oBAAoB,GAAU,0EAMxC;IACD,YAAY,EAAE,MAAM,CAAC;IAGrB,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,KAAG,OAAO,CAAC,2BAA2B,EAAE,CA2CxC,CAAC"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// Host-side Redis command executor. Ported from
|
|
2
|
+
// `pmanfrontend/electron/redis/redisService.ts`. The desktop original resolves
|
|
3
|
+
// connections from a local store (`redisManager`); callman-core has none, so
|
|
4
|
+
// the caller MUST provide the resolved `connection`. `ioredis` is loaded lazily
|
|
5
|
+
// via `loadOptionalModule`.
|
|
6
|
+
import { performance } from "node:perf_hooks";
|
|
7
|
+
import { loadOptionalModule } from "../lazy.js";
|
|
8
|
+
import { resolveTemplate } from "../db/templateResolver.js";
|
|
9
|
+
const unwrap = (mod) => (mod && mod.default ? mod.default : mod);
|
|
10
|
+
const loadRedisDriver = async () => {
|
|
11
|
+
try {
|
|
12
|
+
const mod = await loadOptionalModule("ioredis");
|
|
13
|
+
// ioredis exports both `default` and a named `Redis`. Prefer the named
|
|
14
|
+
// class; fall back to default.
|
|
15
|
+
return mod.Redis ?? unwrap(mod);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new Error("Redis driver (`ioredis`) is not installed. Install `ioredis` to use Redis connections.");
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const REDIS_TOKEN_PATTERN = /"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|(\S+)/g;
|
|
22
|
+
const stripEscapes = (value) => value.replace(/\\(["'\\])/g, "$1");
|
|
23
|
+
const tokenizeRedisCommand = (input) => {
|
|
24
|
+
const tokens = [];
|
|
25
|
+
for (const match of input.matchAll(REDIS_TOKEN_PATTERN)) {
|
|
26
|
+
const [, doubleQuoted, singleQuoted, bare] = match;
|
|
27
|
+
const token = doubleQuoted ?? singleQuoted ?? bare ?? "";
|
|
28
|
+
if (token.length === 0) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
tokens.push(stripEscapes(token));
|
|
32
|
+
}
|
|
33
|
+
return tokens;
|
|
34
|
+
};
|
|
35
|
+
const parseRedisCommand = (command) => {
|
|
36
|
+
const tokens = tokenizeRedisCommand(command.trim());
|
|
37
|
+
if (tokens.length === 0) {
|
|
38
|
+
throw new Error("Redis command cannot be empty");
|
|
39
|
+
}
|
|
40
|
+
const commandName = tokens[0]?.toUpperCase();
|
|
41
|
+
if (commandName !== "GET" &&
|
|
42
|
+
commandName !== "SET" &&
|
|
43
|
+
commandName !== "DEL" &&
|
|
44
|
+
commandName !== "EXISTS" &&
|
|
45
|
+
commandName !== "TTL") {
|
|
46
|
+
throw new Error("Supported Redis commands are GET, SET, DEL, EXISTS, and TTL");
|
|
47
|
+
}
|
|
48
|
+
const key = tokens[1]?.trim() ?? "";
|
|
49
|
+
if (!key) {
|
|
50
|
+
throw new Error(`${commandName} requires a key`);
|
|
51
|
+
}
|
|
52
|
+
if (commandName === "SET") {
|
|
53
|
+
if (tokens.length < 3) {
|
|
54
|
+
throw new Error("SET requires a key and a value");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
commandName,
|
|
58
|
+
key,
|
|
59
|
+
args: [tokens.slice(2).join(" ")],
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (tokens.length > 2) {
|
|
63
|
+
throw new Error(`${commandName} accepts only a single key`);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
commandName,
|
|
67
|
+
key,
|
|
68
|
+
args: [],
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const createRedisClient = async (connection) => {
|
|
72
|
+
const IORedis = await loadRedisDriver();
|
|
73
|
+
return new IORedis({
|
|
74
|
+
host: connection.host,
|
|
75
|
+
port: connection.port,
|
|
76
|
+
password: connection.password,
|
|
77
|
+
db: connection.dbIndex,
|
|
78
|
+
lazyConnect: true,
|
|
79
|
+
enableOfflineQueue: false,
|
|
80
|
+
maxRetriesPerRequest: 1,
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
const stringifyRedisResult = (value) => {
|
|
84
|
+
if (value === null || value === undefined) {
|
|
85
|
+
return "null";
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === "string") {
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === "number" || typeof value === "boolean") {
|
|
91
|
+
return String(value);
|
|
92
|
+
}
|
|
93
|
+
return JSON.stringify(value);
|
|
94
|
+
};
|
|
95
|
+
const normalizeRedisResultValue = (value) => {
|
|
96
|
+
if (value === null || value === undefined) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
if (Buffer.isBuffer(value)) {
|
|
103
|
+
return value.toString("utf-8");
|
|
104
|
+
}
|
|
105
|
+
if (Array.isArray(value)) {
|
|
106
|
+
return value.map((entry) => normalizeRedisResultValue(entry));
|
|
107
|
+
}
|
|
108
|
+
if (typeof value === "object") {
|
|
109
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
110
|
+
key,
|
|
111
|
+
normalizeRedisResultValue(entry),
|
|
112
|
+
]));
|
|
113
|
+
}
|
|
114
|
+
return String(value);
|
|
115
|
+
};
|
|
116
|
+
const executeParsedCommand = async (client, parsedCommand) => {
|
|
117
|
+
switch (parsedCommand.commandName) {
|
|
118
|
+
case "GET":
|
|
119
|
+
return await client.get(parsedCommand.key);
|
|
120
|
+
case "SET":
|
|
121
|
+
await client.set(parsedCommand.key, parsedCommand.args[0] ?? "");
|
|
122
|
+
return parsedCommand.args[0] ?? "";
|
|
123
|
+
case "DEL":
|
|
124
|
+
return await client.del(parsedCommand.key);
|
|
125
|
+
case "EXISTS":
|
|
126
|
+
return (await client.exists(parsedCommand.key)) > 0;
|
|
127
|
+
case "TTL":
|
|
128
|
+
return await client.ttl(parsedCommand.key);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const buildFailureResult = ({ connectionId, connectionName, command, resolvedCommand, phase, error, startedAt, commandName = "", key = null, }) => ({
|
|
132
|
+
success: false,
|
|
133
|
+
phase,
|
|
134
|
+
connectionId,
|
|
135
|
+
connectionName,
|
|
136
|
+
command,
|
|
137
|
+
resolvedCommand,
|
|
138
|
+
commandName,
|
|
139
|
+
key,
|
|
140
|
+
result: null,
|
|
141
|
+
resultText: "",
|
|
142
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
143
|
+
executedAt: new Date().toISOString(),
|
|
144
|
+
error: error instanceof Error ? error.message : String(error),
|
|
145
|
+
});
|
|
146
|
+
const executeResolvedCommand = async ({ client, connection, command, resolvedCommand, phase, }) => {
|
|
147
|
+
const startedAt = performance.now();
|
|
148
|
+
try {
|
|
149
|
+
const parsedCommand = parseRedisCommand(resolvedCommand);
|
|
150
|
+
const rawResult = await executeParsedCommand(client, parsedCommand);
|
|
151
|
+
const normalizedResult = normalizeRedisResultValue(rawResult);
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
phase,
|
|
155
|
+
connectionId: connection.id,
|
|
156
|
+
connectionName: connection.name,
|
|
157
|
+
command,
|
|
158
|
+
resolvedCommand,
|
|
159
|
+
commandName: parsedCommand.commandName,
|
|
160
|
+
key: parsedCommand.key,
|
|
161
|
+
result: normalizedResult,
|
|
162
|
+
resultText: stringifyRedisResult(normalizedResult),
|
|
163
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
164
|
+
executedAt: new Date().toISOString(),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
let commandName = "";
|
|
169
|
+
let key = null;
|
|
170
|
+
try {
|
|
171
|
+
const parsedCommand = parseRedisCommand(resolvedCommand);
|
|
172
|
+
commandName = parsedCommand.commandName;
|
|
173
|
+
key = parsedCommand.key;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// ignore parse failure metadata
|
|
177
|
+
}
|
|
178
|
+
return buildFailureResult({
|
|
179
|
+
connectionId: connection.id,
|
|
180
|
+
connectionName: connection.name,
|
|
181
|
+
command,
|
|
182
|
+
resolvedCommand,
|
|
183
|
+
phase,
|
|
184
|
+
error,
|
|
185
|
+
startedAt,
|
|
186
|
+
commandName,
|
|
187
|
+
key,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const executeWithConnection = async ({ connection, commands, phase, context, }) => {
|
|
192
|
+
if (commands.length === 0) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
const client = await createRedisClient(connection);
|
|
196
|
+
try {
|
|
197
|
+
await client.connect();
|
|
198
|
+
const results = [];
|
|
199
|
+
for (const command of commands) {
|
|
200
|
+
const resolvedCommand = resolveTemplate(command, context ?? {});
|
|
201
|
+
const result = await executeResolvedCommand({
|
|
202
|
+
client,
|
|
203
|
+
connection,
|
|
204
|
+
command,
|
|
205
|
+
resolvedCommand,
|
|
206
|
+
phase,
|
|
207
|
+
});
|
|
208
|
+
results.push(result);
|
|
209
|
+
}
|
|
210
|
+
return results;
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
client.disconnect();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const normalizeConnectionInput = (input) => ({
|
|
217
|
+
id: input.id?.trim() || "runtime-connection",
|
|
218
|
+
name: input.name.trim(),
|
|
219
|
+
type: "redis",
|
|
220
|
+
host: input.host.trim(),
|
|
221
|
+
port: Number(input.port),
|
|
222
|
+
password: input.password?.trim() ? input.password : undefined,
|
|
223
|
+
dbIndex: typeof input.dbIndex === "number" && Number.isFinite(input.dbIndex) && input.dbIndex >= 0
|
|
224
|
+
? Math.trunc(input.dbIndex)
|
|
225
|
+
: undefined,
|
|
226
|
+
});
|
|
227
|
+
export const executeRedisCommands = async ({ connectionId, connection: connectionInput, commands, phase, context, }) => {
|
|
228
|
+
const normalizedCommands = commands.map((command) => command.trim()).filter(Boolean);
|
|
229
|
+
if (normalizedCommands.length === 0) {
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
const connection = connectionInput ? normalizeConnectionInput(connectionInput) : null;
|
|
233
|
+
if (!connection) {
|
|
234
|
+
return normalizedCommands.map((command) => buildFailureResult({
|
|
235
|
+
connectionId,
|
|
236
|
+
connectionName: "",
|
|
237
|
+
command,
|
|
238
|
+
resolvedCommand: command,
|
|
239
|
+
phase,
|
|
240
|
+
error: "Redis connection not found",
|
|
241
|
+
startedAt: performance.now(),
|
|
242
|
+
}));
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
return await executeWithConnection({
|
|
246
|
+
connection,
|
|
247
|
+
commands: normalizedCommands,
|
|
248
|
+
phase,
|
|
249
|
+
context,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
return normalizedCommands.map((command) => buildFailureResult({
|
|
254
|
+
connectionId: connection.id,
|
|
255
|
+
connectionName: connection.name,
|
|
256
|
+
command,
|
|
257
|
+
resolvedCommand: resolveTemplate(command, context ?? {}),
|
|
258
|
+
phase,
|
|
259
|
+
error,
|
|
260
|
+
startedAt: performance.now(),
|
|
261
|
+
}));
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
//# sourceMappingURL=redisService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redisService.js","sourceRoot":"","sources":["../../../src/host/redis/redisService.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,+EAA+E;AAC/E,6EAA6E;AAC7E,gFAAgF;AAChF,4BAA4B;AAE5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAS5D,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAO,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAE3E,MAAM,eAAe,GAAG,KAAK,IAAkB,EAAE;IAC/C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAChD,uEAAuE;QACvE,+BAA+B;QAC/B,OAAO,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAUF,MAAM,mBAAmB,GAAG,gDAAgD,CAAC;AAE7E,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE,CAC7C,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAErC,MAAM,oBAAoB,GAAG,CAAC,KAAa,EAAY,EAAE;IACvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACxD,MAAM,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QACnD,MAAM,KAAK,GAAG,YAAY,IAAI,YAAY,IAAI,IAAI,IAAI,EAAE,CAAC;QAEzD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,SAAS;QACX,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,OAAe,EAAsB,EAAE;IAChE,MAAM,MAAM,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAEpD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAA2B,CAAC;IAEtE,IACE,WAAW,KAAK,KAAK;QACrB,WAAW,KAAK,KAAK;QACrB,WAAW,KAAK,KAAK;QACrB,WAAW,KAAK,QAAQ;QACxB,WAAW,KAAK,KAAK,EACrB,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,GAAG,WAAW,iBAAiB,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QAED,OAAO;YACL,WAAW;YACX,GAAG;YACH,IAAI,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAClC,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,GAAG,WAAW,4BAA4B,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO;QACL,WAAW;QACX,GAAG;QACH,IAAI,EAAE,EAAE;KACT,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,KAAK,EAAE,UAA2B,EAAgB,EAAE;IAC5E,MAAM,OAAO,GAAG,MAAM,eAAe,EAAE,CAAC;IACxC,OAAO,IAAI,OAAO,CAAC;QACjB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,QAAQ,EAAE,UAAU,CAAC,QAAQ;QAC7B,EAAE,EAAE,UAAU,CAAC,OAAO;QACtB,WAAW,EAAE,IAAI;QACjB,kBAAkB,EAAE,KAAK;QACzB,oBAAoB,EAAE,CAAC;KACxB,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,KAAc,EAAU,EAAE;IACtD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,KAAc,EAAW,EAAE;IAC5D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QACzF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;YACrE,GAAG;YACH,yBAAyB,CAAC,KAAK,CAAC;SACjC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,KAAK,EAChC,MAAW,EACX,aAAiC,EACf,EAAE;IACpB,QAAQ,aAAa,CAAC,WAAW,EAAE,CAAC;QAClC,KAAK,KAAK;YACR,OAAO,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7C,KAAK,KAAK;YACR,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,KAAK,KAAK;YACR,OAAO,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7C,KAAK,QAAQ;YACX,OAAO,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACtD,KAAK,KAAK;YACR,OAAO,MAAM,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,EAC1B,YAAY,EACZ,cAAc,EACd,OAAO,EACP,eAAe,EACf,KAAK,EACL,KAAK,EACL,SAAS,EACT,WAAW,GAAG,EAAE,EAChB,GAAG,GAAG,IAAI,GAWX,EAA+B,EAAE,CAAC,CAAC;IAClC,OAAO,EAAE,KAAK;IACd,KAAK;IACL,YAAY;IACZ,cAAc;IACd,OAAO;IACP,eAAe;IACf,WAAW;IACX,GAAG;IACH,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACrD,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACpC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;CAC9D,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,KAAK,EAAE,EACpC,MAAM,EACN,UAAU,EACV,OAAO,EACP,eAAe,EACf,KAAK,GAON,EAAwC,EAAE;IACzC,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACpE,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;QAE9D,OAAO;YACL,OAAO,EAAE,IAAI;YACb,KAAK;YACL,YAAY,EAAE,UAAU,CAAC,EAAE;YAC3B,cAAc,EAAE,UAAU,CAAC,IAAI;YAC/B,OAAO;YACP,eAAe;YACf,WAAW,EAAE,aAAa,CAAC,WAAW;YACtC,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,MAAM,EAAE,gBAAgB;YACxB,UAAU,EAAE,oBAAoB,CAAC,gBAAgB,CAAC;YAClD,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YACrD,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,GAAG,GAAkB,IAAI,CAAC;QAE9B,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;YACzD,WAAW,GAAG,aAAa,CAAC,WAAW,CAAC;YACxC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;QAED,OAAO,kBAAkB,CAAC;YACxB,YAAY,EAAE,UAAU,CAAC,EAAE;YAC3B,cAAc,EAAE,UAAU,CAAC,IAAI;YAC/B,OAAO;YACP,eAAe;YACf,KAAK;YACL,KAAK;YACL,SAAS;YACT,WAAW;YACX,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,KAAK,EAAE,EACnC,UAAU,EACV,QAAQ,EACR,KAAK,EACL,OAAO,GAMR,EAA0C,EAAE;IAC3C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,OAAO,GAAkC,EAAE,CAAC;QAElD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;YAChE,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;gBAC1C,MAAM;gBACN,UAAU;gBACV,OAAO;gBACP,eAAe;gBACf,KAAK;aACN,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAAC,KAA2B,EAAmB,EAAE,CAAC,CAAC;IAClF,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,oBAAoB;IAC5C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;IACvB,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;IACvB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;IAC7D,OAAO,EACL,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC;QACvF,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;QAC3B,CAAC,CAAC,SAAS;CAChB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EACzC,YAAY,EACZ,UAAU,EAAE,eAAe,EAC3B,QAAQ,EACR,KAAK,EACL,OAAO,GASR,EAA0C,EAAE;IAC3C,MAAM,kBAAkB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAErF,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEtF,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACxC,kBAAkB,CAAC;YACjB,YAAY;YACZ,cAAc,EAAE,EAAE;YAClB,OAAO;YACP,eAAe,EAAE,OAAO;YACxB,KAAK;YACL,KAAK,EAAE,4BAA4B;YACnC,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE;SAC7B,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,qBAAqB,CAAC;YACjC,UAAU;YACV,QAAQ,EAAE,kBAAkB;YAC5B,KAAK;YACL,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACxC,kBAAkB,CAAC;YACjB,YAAY,EAAE,UAAU,CAAC,EAAE;YAC3B,cAAc,EAAE,UAAU,CAAC,IAAI;YAC/B,OAAO;YACP,eAAe,EAAE,eAAe,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;YACxD,KAAK;YACL,KAAK;YACL,SAAS,EAAE,WAAW,CAAC,GAAG,EAAE;SAC7B,CAAC,CACH,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type RedisCommandPhase = "pre" | "post" | "manual";
|
|
2
|
+
export interface RedisConnection {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
type: "redis";
|
|
6
|
+
host: string;
|
|
7
|
+
port: number;
|
|
8
|
+
password?: string;
|
|
9
|
+
dbIndex?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface RedisConnectionInput {
|
|
12
|
+
id?: string;
|
|
13
|
+
name: string;
|
|
14
|
+
type: "redis";
|
|
15
|
+
host: string;
|
|
16
|
+
port: number;
|
|
17
|
+
password?: string;
|
|
18
|
+
dbIndex?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface RedisTemplateContext {
|
|
21
|
+
response?: unknown | null;
|
|
22
|
+
env?: Record<string, string>;
|
|
23
|
+
global?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
export interface RedisCommandExecutionResult {
|
|
26
|
+
success: boolean;
|
|
27
|
+
phase: RedisCommandPhase;
|
|
28
|
+
connectionId: string;
|
|
29
|
+
connectionName: string;
|
|
30
|
+
command: string;
|
|
31
|
+
resolvedCommand: string;
|
|
32
|
+
commandName: string;
|
|
33
|
+
key: string | null;
|
|
34
|
+
result: unknown;
|
|
35
|
+
resultText: string;
|
|
36
|
+
durationMs: number;
|
|
37
|
+
executedAt: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface RequestRedisResult {
|
|
41
|
+
pre: RedisCommandExecutionResult[];
|
|
42
|
+
post: RedisCommandExecutionResult[];
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/host/redis/types.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,iBAAiB,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,2BAA2B,EAAE,CAAC;IACnC,IAAI,EAAE,2BAA2B,EAAE,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/host/redis/types.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,0CAA0C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,11 @@ export { EnvStore } from "./variables/envStore.js";
|
|
|
7
7
|
export { runScript } from "./script/legacy.js";
|
|
8
8
|
export * from "./templating/index.js";
|
|
9
9
|
export { executeScript, validateScript } from "./script/executor.js";
|
|
10
|
+
export { runScriptIsolated } from "./script/isolated-runner.js";
|
|
11
|
+
export type { RunScriptIsolatedOptions } from "./script/isolated-runner.js";
|
|
10
12
|
export type { CounterSnapshotEntry, ExecuteScriptInput, ExecuteScriptResult, ScriptCapabilities, ScriptCounterCapability, ScriptDbCapability, ScriptDbExecutionInput, ScriptDbExecutionResult, ScriptError, ScriptFeaturePolicy, ScriptKafkaCapability, ScriptKeyValuePair, ScriptLogEntry, ScriptRedisCapability, ScriptRequestBodyState, ScriptRequestState, ScriptResponseState, ScriptStage, ScriptTestResult, ScriptVariableMutation, SendRequestExecutor, } from "./script/types.js";
|
|
13
|
+
export { PM_API_METADATA, type PmApiMember, type PmApiNamespace, type PmApiStage, } from "./script/pm-api-metadata.js";
|
|
14
|
+
export { ALLOWED_GLOBAL_NAMES, BLOCKED_GLOBAL_NAMES, RESERVED_LABEL_NAMES, } from "./script/scope.js";
|
|
11
15
|
export { PmAssertion, createExpectApi } from "./script/features/assertions.js";
|
|
12
16
|
export { PendingKafkaDependencyError, isPendingKafkaValue, } from "./script/features/kafka.js";
|
|
13
17
|
export { DisabledFeatureDependencyError, isDisabledFeatureValue, } from "./script/features/feature-policy.js";
|
|
@@ -15,5 +19,6 @@ export { validateContracts, evaluateContractCandidate, normalizeContractRule, ty
|
|
|
15
19
|
export { resolveContractPath, generalizeContractPath, normalizeContractPathKey, type ResolvedCandidate, } from "./contract/pathResolver.js";
|
|
16
20
|
export { SCENARIO_CONTRACT_FORMATS, FORMAT_VALIDATORS, isContractFormat, type ContractFormat, } from "./contract/formats.js";
|
|
17
21
|
export * from "./scenario-runner/index.js";
|
|
22
|
+
export * from "./host/index.js";
|
|
18
23
|
export * from "./types/index.js";
|
|
19
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,wBAAwB,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,kBAAkB,EAClB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,YAAY,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,WAAW,EACX,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,UAAU,GAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,wBAAwB,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,EACxB,KAAK,iBAAiB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,9 @@ export { EnvStore } from "./variables/envStore.js";
|
|
|
7
7
|
export { runScript } from "./script/legacy.js";
|
|
8
8
|
export * from "./templating/index.js";
|
|
9
9
|
export { executeScript, validateScript } from "./script/executor.js";
|
|
10
|
+
export { runScriptIsolated } from "./script/isolated-runner.js";
|
|
11
|
+
export { PM_API_METADATA, } from "./script/pm-api-metadata.js";
|
|
12
|
+
export { ALLOWED_GLOBAL_NAMES, BLOCKED_GLOBAL_NAMES, RESERVED_LABEL_NAMES, } from "./script/scope.js";
|
|
10
13
|
export { PmAssertion, createExpectApi } from "./script/features/assertions.js";
|
|
11
14
|
export { PendingKafkaDependencyError, isPendingKafkaValue, } from "./script/features/kafka.js";
|
|
12
15
|
export { DisabledFeatureDependencyError, isDisabledFeatureValue, } from "./script/features/feature-policy.js";
|
|
@@ -14,5 +17,6 @@ export { validateContracts, evaluateContractCandidate, normalizeContractRule, }
|
|
|
14
17
|
export { resolveContractPath, generalizeContractPath, normalizeContractPathKey, } from "./contract/pathResolver.js";
|
|
15
18
|
export { SCENARIO_CONTRACT_FORMATS, FORMAT_VALIDATORS, isContractFormat, } from "./contract/formats.js";
|
|
16
19
|
export * from "./scenario-runner/index.js";
|
|
20
|
+
export * from "./host/index.js";
|
|
17
21
|
export * from "./types/index.js";
|
|
18
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,kBAAkB,GAEnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAyBhE,OAAO,EACL,eAAe,GAIhB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,GAEtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,wBAAwB,GAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GAEjB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestRunner.d.ts","sourceRoot":"","sources":["../../src/runner/requestRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"requestRunner.d.ts","sourceRoot":"","sources":["../../src/runner/requestRunner.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAGV,eAAe,EACf,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AA0K3B,eAAO,MAAM,UAAU,GACrB,OAAO,eAAe,KACrB,OAAO,CAAC,gBAAgB,CAiG1B,CAAC"}
|
|
@@ -1,7 +1,47 @@
|
|
|
1
1
|
import { validateContracts } from "../contract/contractValidator.js";
|
|
2
|
+
import { buildDbExecuteCapability, buildRedisCapability, runConfiguredDbQuery, runRedisCommandsForPhase, } from "../host/connections.js";
|
|
2
3
|
import { executeRequest } from "../request/executeRequest.js";
|
|
3
4
|
import { runScript } from "../script/scriptEngine.js";
|
|
4
5
|
import { resolveTemplateValue } from "../variables/resolver.js";
|
|
6
|
+
const stringifyEnv = (env) => {
|
|
7
|
+
const out = {};
|
|
8
|
+
for (const [key, value] of Object.entries(env)) {
|
|
9
|
+
out[key] = value === undefined || value === null ? "" : String(value);
|
|
10
|
+
}
|
|
11
|
+
return out;
|
|
12
|
+
};
|
|
13
|
+
// Build a `{{response.*}}` template root from an HTTP result so pre/post DB +
|
|
14
|
+
// Redis nodes can reference the response body. Mirrors the desktop host's
|
|
15
|
+
// `buildResponseTemplateRoot`.
|
|
16
|
+
const buildResponseRoot = (response) => {
|
|
17
|
+
if (!response) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const data = response.data;
|
|
21
|
+
const isObject = data !== null && typeof data === "object" && !Array.isArray(data);
|
|
22
|
+
const rawText = response.rawText ?? (typeof data === "string" ? data : safeStringify(data));
|
|
23
|
+
return {
|
|
24
|
+
...(isObject ? data : {}),
|
|
25
|
+
data: isObject && "data" in data
|
|
26
|
+
? data.data
|
|
27
|
+
: data,
|
|
28
|
+
body: data,
|
|
29
|
+
rawBody: rawText,
|
|
30
|
+
text: rawText,
|
|
31
|
+
status: response.status,
|
|
32
|
+
code: response.status,
|
|
33
|
+
headers: response.headers,
|
|
34
|
+
durationMs: response.duration,
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
const safeStringify = (value) => {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.stringify(value);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return String(value);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
5
45
|
const resolveHeaders = (headers, context) => {
|
|
6
46
|
if (!headers) {
|
|
7
47
|
return undefined;
|
|
@@ -54,15 +94,95 @@ const normalizeRequestForExecution = ({ request, env, previousResponse, }) => {
|
|
|
54
94
|
body: resolveTemplateValue(request.body, resolveContext),
|
|
55
95
|
};
|
|
56
96
|
};
|
|
97
|
+
// Wires the resolved connections + request DB/Redis config into the script
|
|
98
|
+
// capabilities. Runs the pre-request DB node + pre Redis commands before this
|
|
99
|
+
// is called, the post ones after the response. Returns the capabilities to
|
|
100
|
+
// hand to `runScript` plus the redis results gathered so far.
|
|
101
|
+
const buildScriptExtensions = (input) => {
|
|
102
|
+
const db = input.databaseEnabled
|
|
103
|
+
? {
|
|
104
|
+
execute: buildDbExecuteCapability(input.connections),
|
|
105
|
+
preResult: input.preDbResult,
|
|
106
|
+
postResult: input.postDbResult,
|
|
107
|
+
requestConfig: {
|
|
108
|
+
preRequest: {
|
|
109
|
+
connectionId: input.request.database?.preRequest?.connectionId ?? undefined,
|
|
110
|
+
},
|
|
111
|
+
postResponse: {
|
|
112
|
+
connectionId: input.request.database?.postResponse?.connectionId ?? undefined,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}
|
|
116
|
+
: undefined;
|
|
117
|
+
const hasRedis = Boolean(input.request.redis?.connectionId) &&
|
|
118
|
+
(input.redisPre.length > 0 || input.redisPost.length > 0 ||
|
|
119
|
+
(input.request.redis?.preCommands?.length ?? 0) > 0 ||
|
|
120
|
+
(input.request.redis?.postCommands?.length ?? 0) > 0);
|
|
121
|
+
const redis = hasRedis
|
|
122
|
+
? buildRedisCapability(input.redisPre, input.redisPost)
|
|
123
|
+
: undefined;
|
|
124
|
+
return { db, redis };
|
|
125
|
+
};
|
|
57
126
|
export const runRequest = async (input) => {
|
|
58
127
|
const runtimeRequest = normalizeRequestForExecution(input);
|
|
128
|
+
const connections = input.connections ?? {};
|
|
129
|
+
const featurePolicy = input.featurePolicy;
|
|
130
|
+
const databaseEnabled = featurePolicy ? featurePolicy.database : true;
|
|
131
|
+
const redisConfig = input.request.redis;
|
|
59
132
|
try {
|
|
133
|
+
// ── Pre-request phase: DB node + Redis commands run before the HTTP call.
|
|
134
|
+
const envBefore = stringifyEnv(input.env.all());
|
|
135
|
+
const preDbResult = databaseEnabled
|
|
136
|
+
? await runConfiguredDbQuery({
|
|
137
|
+
connections,
|
|
138
|
+
config: input.request.database?.preRequest,
|
|
139
|
+
phase: "pre",
|
|
140
|
+
context: { response: null, env: envBefore, global: {} },
|
|
141
|
+
})
|
|
142
|
+
: null;
|
|
143
|
+
const redisPre = await runRedisCommandsForPhase({
|
|
144
|
+
connections,
|
|
145
|
+
connectionId: redisConfig?.connectionId,
|
|
146
|
+
commands: redisConfig?.preCommands ?? [],
|
|
147
|
+
phase: "pre",
|
|
148
|
+
context: { response: null, env: envBefore, global: {} },
|
|
149
|
+
});
|
|
60
150
|
const response = await executeRequest(runtimeRequest);
|
|
61
151
|
const contractResults = validateContracts(input.request.contracts, response);
|
|
152
|
+
const responseRoot = buildResponseRoot(response);
|
|
153
|
+
// ── Post-response phase: DB node + Redis commands run after the response.
|
|
154
|
+
const envAfter = stringifyEnv(input.env.all());
|
|
155
|
+
const postDbResult = databaseEnabled
|
|
156
|
+
? await runConfiguredDbQuery({
|
|
157
|
+
connections,
|
|
158
|
+
config: input.request.database?.postResponse,
|
|
159
|
+
phase: "post",
|
|
160
|
+
context: { response: responseRoot, env: envAfter, global: {} },
|
|
161
|
+
})
|
|
162
|
+
: null;
|
|
163
|
+
const redisPost = await runRedisCommandsForPhase({
|
|
164
|
+
connections,
|
|
165
|
+
connectionId: redisConfig?.connectionId,
|
|
166
|
+
commands: redisConfig?.postCommands ?? [],
|
|
167
|
+
phase: "post",
|
|
168
|
+
context: { response: responseRoot, env: envAfter, global: {} },
|
|
169
|
+
});
|
|
170
|
+
const { db, redis } = buildScriptExtensions({
|
|
171
|
+
connections,
|
|
172
|
+
databaseEnabled,
|
|
173
|
+
request: input.request,
|
|
174
|
+
preDbResult,
|
|
175
|
+
postDbResult,
|
|
176
|
+
redisPre,
|
|
177
|
+
redisPost,
|
|
178
|
+
});
|
|
62
179
|
const scriptResults = await runScript(input.request.tests, {
|
|
63
180
|
env: input.env,
|
|
64
181
|
response,
|
|
65
182
|
request: runtimeRequest,
|
|
183
|
+
db,
|
|
184
|
+
redis,
|
|
185
|
+
featurePolicy,
|
|
66
186
|
});
|
|
67
187
|
return {
|
|
68
188
|
response,
|