taurusdb-core 0.5.0-rc.10 → 0.5.0-rc.2
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/dist/auth/sql-profile-loader/env-source.js +20 -6
- package/dist/auth/sql-profile-loader/parsing.js +9 -3
- package/dist/auth/sql-profile-loader/types.d.ts +3 -1
- package/dist/config/env.js +1 -3
- package/dist/config/schema.d.ts +5 -15
- package/dist/config/schema.js +3 -5
- package/dist/engine.d.ts +2 -1
- package/dist/engine.js +7 -1
- package/dist/executor/connection-pool.js +8 -7
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -1
- package/dist/safety/sql-validator.js +1 -1
- package/dist/utils/formatter.d.ts +0 -5
- package/dist/utils/formatter.js +0 -5
- package/package.json +1 -1
|
@@ -12,8 +12,7 @@ export function parseEngineFromDsnProtocol(protocol) {
|
|
|
12
12
|
export function parseEnvProfile(env) {
|
|
13
13
|
const dsn = asString(env.TAURUSDB_SQL_DSN);
|
|
14
14
|
const explicitHost = asString(env.TAURUSDB_SQL_HOST);
|
|
15
|
-
const
|
|
16
|
-
const profileName = explicitProfileName ?? "taurus_mcp";
|
|
15
|
+
const profileName = asString(env.TAURUSDB_SQL_DATASOURCE) ?? "taurus_mcp";
|
|
17
16
|
let engine;
|
|
18
17
|
let host;
|
|
19
18
|
let port;
|
|
@@ -41,7 +40,6 @@ export function parseEnvProfile(env) {
|
|
|
41
40
|
}
|
|
42
41
|
if (!dsn &&
|
|
43
42
|
!explicitHost &&
|
|
44
|
-
!explicitProfileName &&
|
|
45
43
|
!asString(env.TAURUSDB_SQL_USER) &&
|
|
46
44
|
!asString(env.TAURUSDB_SQL_PASSWORD) &&
|
|
47
45
|
!database) {
|
|
@@ -51,13 +49,23 @@ export function parseEnvProfile(env) {
|
|
|
51
49
|
throw new Error("Failed to resolve SQL port from environment.");
|
|
52
50
|
}
|
|
53
51
|
username = username ?? asString(env.TAURUSDB_SQL_USER);
|
|
52
|
+
if (!username) {
|
|
53
|
+
throw new Error("Missing SQL username in environment. Set TAURUSDB_SQL_USER or include it in DSN.");
|
|
54
|
+
}
|
|
54
55
|
passwordRef =
|
|
55
56
|
passwordRef ??
|
|
56
57
|
(Object.hasOwn(env, "TAURUSDB_SQL_PASSWORD")
|
|
57
58
|
? parseCredentialRef(env.TAURUSDB_SQL_PASSWORD, "TAURUSDB_SQL_PASSWORD")
|
|
58
59
|
: undefined);
|
|
59
|
-
if (
|
|
60
|
-
throw new Error("SQL
|
|
60
|
+
if (!passwordRef) {
|
|
61
|
+
throw new Error("Missing SQL password in environment. Set TAURUSDB_SQL_PASSWORD or include it in DSN.");
|
|
62
|
+
}
|
|
63
|
+
const mutationUsername = asString(env.TAURUSDB_SQL_MUTATION_USER);
|
|
64
|
+
const mutationPasswordRef = Object.hasOwn(env, "TAURUSDB_SQL_MUTATION_PASSWORD")
|
|
65
|
+
? parseCredentialRef(env.TAURUSDB_SQL_MUTATION_PASSWORD, "TAURUSDB_SQL_MUTATION_PASSWORD")
|
|
66
|
+
: undefined;
|
|
67
|
+
if ((mutationUsername && !mutationPasswordRef) || (!mutationUsername && mutationPasswordRef)) {
|
|
68
|
+
throw new Error("Mutation credentials require both TAURUSDB_SQL_MUTATION_USER and TAURUSDB_SQL_MUTATION_PASSWORD.");
|
|
61
69
|
}
|
|
62
70
|
const poolSize = asInteger(env.TAURUSDB_SQL_POOL_SIZE);
|
|
63
71
|
if (poolSize !== undefined && poolSize <= 0) {
|
|
@@ -69,7 +77,13 @@ export function parseEnvProfile(env) {
|
|
|
69
77
|
host,
|
|
70
78
|
port,
|
|
71
79
|
database,
|
|
72
|
-
user:
|
|
80
|
+
user: {
|
|
81
|
+
username,
|
|
82
|
+
password: passwordRef,
|
|
83
|
+
},
|
|
84
|
+
mutationUser: mutationUsername && mutationPasswordRef
|
|
85
|
+
? { username: mutationUsername, password: mutationPasswordRef }
|
|
86
|
+
: undefined,
|
|
73
87
|
poolSize,
|
|
74
88
|
});
|
|
75
89
|
}
|
|
@@ -196,14 +196,19 @@ export function parseProfileRecord(name, value, context) {
|
|
|
196
196
|
if (poolSize !== undefined && poolSize <= 0) {
|
|
197
197
|
throw new Error(`Invalid datasource profile ${name} in ${context}: poolSize must be positive.`);
|
|
198
198
|
}
|
|
199
|
-
// `user` is the
|
|
199
|
+
// `user` is the read-only credential. Keep older read-only aliases for compatibility.
|
|
200
200
|
const userRaw = value.user ??
|
|
201
201
|
value.readonlyUser ??
|
|
202
202
|
value.readonly ??
|
|
203
203
|
value.readOnlyUser;
|
|
204
|
-
|
|
204
|
+
if (userRaw === undefined) {
|
|
205
|
+
throw new Error(`Invalid datasource profile ${name} in ${context}: missing user.`);
|
|
206
|
+
}
|
|
207
|
+
const user = parseUserCredential(userRaw, `${context}.${name}.user`);
|
|
208
|
+
const mutationUserRaw = value.mutationUser ?? value.writeUser ?? value.rwUser;
|
|
209
|
+
const mutationUser = mutationUserRaw === undefined
|
|
205
210
|
? undefined
|
|
206
|
-
: parseUserCredential(
|
|
211
|
+
: parseUserCredential(mutationUserRaw, `${context}.${name}.mutationUser`);
|
|
207
212
|
const tls = parseTlsOptions(value.tls, `${context}.${name}.tls`);
|
|
208
213
|
return withRedactedToString({
|
|
209
214
|
name,
|
|
@@ -214,6 +219,7 @@ export function parseProfileRecord(name, value, context) {
|
|
|
214
219
|
instanceId,
|
|
215
220
|
nodeId,
|
|
216
221
|
user,
|
|
222
|
+
mutationUser,
|
|
217
223
|
tls,
|
|
218
224
|
poolSize,
|
|
219
225
|
});
|
|
@@ -33,8 +33,10 @@ export interface DataSourceProfile {
|
|
|
33
33
|
database?: string;
|
|
34
34
|
instanceId?: string;
|
|
35
35
|
nodeId?: string;
|
|
36
|
-
/**
|
|
36
|
+
/** Read-only credential used by discovery, diagnostics, and query tools. */
|
|
37
37
|
user?: UserCredential;
|
|
38
|
+
/** Separate credential required for mutation tools. No fallback is allowed. */
|
|
39
|
+
mutationUser?: UserCredential;
|
|
38
40
|
tls?: TlsOptions;
|
|
39
41
|
poolSize?: number;
|
|
40
42
|
toString(): string;
|
package/dist/config/env.js
CHANGED
|
@@ -160,13 +160,11 @@ export function buildRawConfigFromEnv(env) {
|
|
|
160
160
|
maxFiles: parseInteger(env.TAURUSDB_MCP_AUDIT_MAX_FILES, "TAURUSDB_MCP_AUDIT_MAX_FILES"),
|
|
161
161
|
},
|
|
162
162
|
security: {
|
|
163
|
+
mutationsEnabled: parseBoolean(env.TAURUSDB_ENABLE_MUTATIONS, "TAURUSDB_ENABLE_MUTATIONS"),
|
|
163
164
|
dynamicTargetsEnabled: parseBoolean(env.TAURUSDB_ENABLE_DYNAMIC_TARGETS, "TAURUSDB_ENABLE_DYNAMIC_TARGETS"),
|
|
164
|
-
recycleBinRestoreEnabled: parseBoolean(env.TAURUSDB_ENABLE_RECYCLE_BIN_RESTORE, "TAURUSDB_ENABLE_RECYCLE_BIN_RESTORE"),
|
|
165
165
|
requireTls: parseBoolean(env.TAURUSDB_REQUIRE_TLS, "TAURUSDB_REQUIRE_TLS"),
|
|
166
166
|
approvalSecretPath: expandTildePath(readString(env.TAURUSDB_MUTATION_APPROVAL_SECRET_FILE)),
|
|
167
167
|
approvalTtlSeconds: parseInteger(env.TAURUSDB_MUTATION_APPROVAL_TTL_SECONDS, "TAURUSDB_MUTATION_APPROVAL_TTL_SECONDS"),
|
|
168
|
-
credentialIdleTtlMinutes: parseInteger(env.TAURUSDB_SQL_CREDENTIAL_IDLE_TTL_MINUTES, "TAURUSDB_SQL_CREDENTIAL_IDLE_TTL_MINUTES"),
|
|
169
|
-
credentialMaxTtlMinutes: parseInteger(env.TAURUSDB_SQL_CREDENTIAL_MAX_TTL_MINUTES, "TAURUSDB_SQL_CREDENTIAL_MAX_TTL_MINUTES"),
|
|
170
168
|
},
|
|
171
169
|
slowSqlSource: {
|
|
172
170
|
taurusApi: {
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -105,29 +105,23 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
105
105
|
maxFiles?: number | undefined;
|
|
106
106
|
}>>;
|
|
107
107
|
security: z.ZodDefault<z.ZodObject<{
|
|
108
|
+
mutationsEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
108
109
|
dynamicTargetsEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
109
|
-
recycleBinRestoreEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
110
110
|
requireTls: z.ZodDefault<z.ZodBoolean>;
|
|
111
111
|
approvalSecretPath: z.ZodOptional<z.ZodString>;
|
|
112
112
|
approvalTtlSeconds: z.ZodDefault<z.ZodNumber>;
|
|
113
|
-
credentialIdleTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
114
|
-
credentialMaxTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
115
113
|
}, "strip", z.ZodTypeAny, {
|
|
114
|
+
mutationsEnabled: boolean;
|
|
116
115
|
dynamicTargetsEnabled: boolean;
|
|
117
|
-
recycleBinRestoreEnabled: boolean;
|
|
118
116
|
requireTls: boolean;
|
|
119
117
|
approvalTtlSeconds: number;
|
|
120
|
-
credentialIdleTtlMinutes: number;
|
|
121
|
-
credentialMaxTtlMinutes: number;
|
|
122
118
|
approvalSecretPath?: string | undefined;
|
|
123
119
|
}, {
|
|
120
|
+
mutationsEnabled?: boolean | undefined;
|
|
124
121
|
dynamicTargetsEnabled?: boolean | undefined;
|
|
125
|
-
recycleBinRestoreEnabled?: boolean | undefined;
|
|
126
122
|
requireTls?: boolean | undefined;
|
|
127
123
|
approvalSecretPath?: string | undefined;
|
|
128
124
|
approvalTtlSeconds?: number | undefined;
|
|
129
|
-
credentialIdleTtlMinutes?: number | undefined;
|
|
130
|
-
credentialMaxTtlMinutes?: number | undefined;
|
|
131
125
|
}>>;
|
|
132
126
|
slowSqlSource: z.ZodDefault<z.ZodObject<{
|
|
133
127
|
taurusApi: z.ZodDefault<z.ZodObject<{
|
|
@@ -364,12 +358,10 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
364
358
|
maxFiles: number;
|
|
365
359
|
};
|
|
366
360
|
security: {
|
|
361
|
+
mutationsEnabled: boolean;
|
|
367
362
|
dynamicTargetsEnabled: boolean;
|
|
368
|
-
recycleBinRestoreEnabled: boolean;
|
|
369
363
|
requireTls: boolean;
|
|
370
364
|
approvalTtlSeconds: number;
|
|
371
|
-
credentialIdleTtlMinutes: number;
|
|
372
|
-
credentialMaxTtlMinutes: number;
|
|
373
365
|
approvalSecretPath?: string | undefined;
|
|
374
366
|
};
|
|
375
367
|
slowSqlSource: {
|
|
@@ -457,13 +449,11 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
457
449
|
maxFiles?: number | undefined;
|
|
458
450
|
} | undefined;
|
|
459
451
|
security?: {
|
|
452
|
+
mutationsEnabled?: boolean | undefined;
|
|
460
453
|
dynamicTargetsEnabled?: boolean | undefined;
|
|
461
|
-
recycleBinRestoreEnabled?: boolean | undefined;
|
|
462
454
|
requireTls?: boolean | undefined;
|
|
463
455
|
approvalSecretPath?: string | undefined;
|
|
464
456
|
approvalTtlSeconds?: number | undefined;
|
|
465
|
-
credentialIdleTtlMinutes?: number | undefined;
|
|
466
|
-
credentialMaxTtlMinutes?: number | undefined;
|
|
467
457
|
} | undefined;
|
|
468
458
|
slowSqlSource?: {
|
|
469
459
|
taurusApi?: {
|
package/dist/config/schema.js
CHANGED
|
@@ -22,13 +22,11 @@ const AuditSchema = z
|
|
|
22
22
|
.default({});
|
|
23
23
|
const SecuritySchema = z
|
|
24
24
|
.object({
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
requireTls: z.boolean().default(
|
|
25
|
+
mutationsEnabled: z.boolean().default(false),
|
|
26
|
+
dynamicTargetsEnabled: z.boolean().default(false),
|
|
27
|
+
requireTls: z.boolean().default(true),
|
|
28
28
|
approvalSecretPath: z.string().min(1).optional(),
|
|
29
29
|
approvalTtlSeconds: z.number().int().positive().max(3600).default(300),
|
|
30
|
-
credentialIdleTtlMinutes: z.number().int().positive().max(30).default(30),
|
|
31
|
-
credentialMaxTtlMinutes: z.number().int().positive().max(480).default(480),
|
|
32
30
|
})
|
|
33
31
|
.default({});
|
|
34
32
|
const CloudSchema = z
|
package/dist/engine.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { type ConfirmationStore, type ConfirmationRequest, type ConfirmationVali
|
|
|
10
10
|
import { type Guardrail, type GuardrailDecision, type InspectInput } from "./safety/guardrail.js";
|
|
11
11
|
import { type DatabaseInfo, type SchemaIntrospector, type TableInfo, type TableSchema } from "./schema/introspector.js";
|
|
12
12
|
import { type FlashbackInput } from "./taurus/flashback.js";
|
|
13
|
-
import type
|
|
13
|
+
import { type RestoreRecycleBinTableInput } from "./taurus/recycle-bin.js";
|
|
14
14
|
import { type DbHotspotResult, type DiagnoseDbHotspotInput, type DiagnoseServiceLatencyInput, type FindTopSlowSqlInput, type FindTopSlowSqlResult, type DiagnoseConnectionSpikeInput, type DiagnoseLockContentionInput, type DiagnoseSlowQueryInput, type DiagnoseStoragePressureInput, type DiagnoseReplicationLagInput, type DiagnosticResult, type ServiceLatencyResult } from "./diagnostics/types.js";
|
|
15
15
|
import { type SlowSqlSource } from "./diagnostics/slow-sql-source.js";
|
|
16
16
|
import { type MetricsSource } from "./diagnostics/metrics-source.js";
|
|
@@ -65,6 +65,7 @@ export declare class TaurusDBEngine {
|
|
|
65
65
|
explain(sql: string, ctx: SessionContext): Promise<ExplainResult>;
|
|
66
66
|
explainEnhanced(sql: string, ctx: SessionContext): Promise<EnhancedExplainResult>;
|
|
67
67
|
executeReadonly(sql: string, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
68
|
+
executeMutation(sql: string, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
68
69
|
flashbackQuery(input: FlashbackInput, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
69
70
|
listRecycleBin(ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
70
71
|
restoreRecycleBinTable(input: RestoreRecycleBinTableInput, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
package/dist/engine.js
CHANGED
|
@@ -18,7 +18,7 @@ import { createSlowSqlSource, } from "./diagnostics/slow-sql-source.js";
|
|
|
18
18
|
import { createMetricsSource, } from "./diagnostics/metrics-source.js";
|
|
19
19
|
import { findLatestDeadlock, findMetadataLockWaits, findStatementDigestCandidatesForSqlHints, findStatementDigestSample, findStatementDigestSampleForSql, findStatementWaitEvents, findStorageStatementDigests, findTableStorageStats, findTopStatementDigests, isPerformanceSchemaEnabled, showLockWaits, showProcesslist, } from "./engine/data-access.js";
|
|
20
20
|
import { diagnoseConnectionSpike, diagnoseDbHotspot, diagnoseLockContention, diagnoseServiceLatency, diagnoseSlowQuery, diagnoseStoragePressure, findTopSlowSql, } from "./engine/diagnostics.js";
|
|
21
|
-
import { cancelQuery, close, executeReadonly, explain, explainEnhanced, flashbackQuery, getQueryStatus, handleConfirmation, issueConfirmation, listRecycleBin, restoreRecycleBinTable, validateConfirmation, } from "./engine/runtime.js";
|
|
21
|
+
import { cancelQuery, close, executeMutation, executeReadonly, explain, explainEnhanced, flashbackQuery, getQueryStatus, handleConfirmation, issueConfirmation, listRecycleBin, restoreRecycleBinTable, validateConfirmation, } from "./engine/runtime.js";
|
|
22
22
|
async function readMutationApprovalSecret(filePath) {
|
|
23
23
|
const info = await lstat(filePath);
|
|
24
24
|
if (!info.isFile() || info.isSymbolicLink()) {
|
|
@@ -114,6 +114,9 @@ export class TaurusDBEngine {
|
|
|
114
114
|
if (config.security.approvalSecretPath) {
|
|
115
115
|
approvalSecret = await readMutationApprovalSecret(config.security.approvalSecretPath);
|
|
116
116
|
}
|
|
117
|
+
if (config.security.mutationsEnabled && !approvalSecret && !options.confirmationStore) {
|
|
118
|
+
throw new Error("Mutations require TAURUSDB_MUTATION_APPROVAL_SECRET_FILE with at least 32 bytes.");
|
|
119
|
+
}
|
|
117
120
|
const confirmationStore = options.confirmationStore ??
|
|
118
121
|
createConfirmationStore({
|
|
119
122
|
approvalSecret,
|
|
@@ -245,6 +248,9 @@ export class TaurusDBEngine {
|
|
|
245
248
|
async executeReadonly(sql, ctx, opts) {
|
|
246
249
|
return executeReadonly(this, sql, ctx, opts);
|
|
247
250
|
}
|
|
251
|
+
async executeMutation(sql, ctx, opts) {
|
|
252
|
+
return executeMutation(this, sql, ctx, opts);
|
|
253
|
+
}
|
|
248
254
|
async flashbackQuery(input, ctx, opts) {
|
|
249
255
|
return flashbackQuery(this, input, ctx, opts);
|
|
250
256
|
}
|
|
@@ -20,12 +20,12 @@ async function resolveTls(tls, secretResolver, host, requireTls) {
|
|
|
20
20
|
if (requireTls && tls?.enabled === false) {
|
|
21
21
|
throw new ConnectionPoolError("TLS is required by server policy and cannot be disabled for this datasource.");
|
|
22
22
|
}
|
|
23
|
+
if (requireTls && tls?.rejectUnauthorized === false) {
|
|
24
|
+
throw new ConnectionPoolError("TLS certificate verification is required by server policy.");
|
|
25
|
+
}
|
|
23
26
|
const resolved = {
|
|
24
27
|
enabled: tls?.enabled ?? true,
|
|
25
|
-
|
|
26
|
-
// certificate is issued to a DNS name. When TLS is explicitly enabled,
|
|
27
|
-
// make CA/hostname verification a separate profile opt-in.
|
|
28
|
-
rejectUnauthorized: tls?.rejectUnauthorized ?? false,
|
|
28
|
+
rejectUnauthorized: tls?.rejectUnauthorized ?? true,
|
|
29
29
|
servername: tls?.servername ?? (isIP(host) === 0 ? host : undefined),
|
|
30
30
|
};
|
|
31
31
|
if (tls?.ca) {
|
|
@@ -39,10 +39,11 @@ async function resolveTls(tls, secretResolver, host, requireTls) {
|
|
|
39
39
|
}
|
|
40
40
|
return resolved;
|
|
41
41
|
}
|
|
42
|
-
function selectCredential(profile,
|
|
43
|
-
const credential = profile.user;
|
|
42
|
+
function selectCredential(profile, mode) {
|
|
43
|
+
const credential = mode === "rw" ? profile.mutationUser : profile.user;
|
|
44
44
|
if (!credential) {
|
|
45
|
-
|
|
45
|
+
const credentialKind = mode === "rw" ? "mutation" : "read-only";
|
|
46
|
+
throw new ConnectionPoolError(`Datasource "${profile.name}" does not define ${credentialKind} SQL credentials. Configure a dedicated ${credentialKind} database username and password reference.`);
|
|
46
47
|
}
|
|
47
48
|
return credential;
|
|
48
49
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,8 +18,6 @@ export type { CapabilitySnapshot, FeatureMatrix, FeatureStatus, KernelInfo, Taur
|
|
|
18
18
|
export { createConfirmationStore, InMemoryConfirmationStore, parseApprovalRequest, signApprovalRequest, } from "./safety/confirmation-store.js";
|
|
19
19
|
export type { ConfirmationStore, ConfirmationRequest, ConfirmationValidationResult, IssueInput, } from "./safety/confirmation-store.js";
|
|
20
20
|
export { createGuardrail } from "./safety/guardrail.js";
|
|
21
|
-
export { createSqlParser } from "./safety/parser/index.js";
|
|
22
|
-
export type { SqlAst, StatementType as ParsedStatementType } from "./safety/parser/index.js";
|
|
23
21
|
export type { Guardrail, GuardrailDecision, GuardrailRuntimeLimits, InspectInput, } from "./safety/guardrail.js";
|
|
24
22
|
export type { ExplainRiskSummary, RiskLevel, ValidationResult } from "./safety/sql-validator.js";
|
|
25
23
|
export { SchemaIntrospectionError } from "./schema/introspector.js";
|
package/dist/index.js
CHANGED
|
@@ -10,7 +10,6 @@ export { createCapabilityProbe } from "./capability/probe.js";
|
|
|
10
10
|
export { UnsupportedFeatureError } from "./capability/types.js";
|
|
11
11
|
export { createConfirmationStore, InMemoryConfirmationStore, parseApprovalRequest, signApprovalRequest, } from "./safety/confirmation-store.js";
|
|
12
12
|
export { createGuardrail } from "./safety/guardrail.js";
|
|
13
|
-
export { createSqlParser } from "./safety/parser/index.js";
|
|
14
13
|
export { SchemaIntrospectionError } from "./schema/introspector.js";
|
|
15
14
|
export { ErrorCode, formatBlocked, formatConfirmationRequired, formatError, formatSuccess, } from "./utils/formatter.js";
|
|
16
15
|
export { normalizeSql, sqlHash } from "./utils/hash.js";
|
|
@@ -54,7 +54,7 @@ export function validateToolScope(toolName, cls) {
|
|
|
54
54
|
if (!READONLY_STATEMENTS.has(cls.statementType)) {
|
|
55
55
|
return block(["T001"], [
|
|
56
56
|
`Tool execute_readonly_sql only allows SELECT/SHOW/EXPLAIN/DESCRIBE, got ${cls.statementType}.`,
|
|
57
|
-
"Use
|
|
57
|
+
"Use execute_sql for controlled mutations.",
|
|
58
58
|
]);
|
|
59
59
|
}
|
|
60
60
|
return allow("low");
|
|
@@ -10,11 +10,6 @@ export declare const ErrorCode: {
|
|
|
10
10
|
readonly QUERY_TIMEOUT: "QUERY_TIMEOUT";
|
|
11
11
|
readonly QUERY_CANCELLED: "QUERY_CANCELLED";
|
|
12
12
|
readonly CONNECTION_FAILED: "CONNECTION_FAILED";
|
|
13
|
-
readonly DB_ENDPOINT_UNREACHABLE: "DB_ENDPOINT_UNREACHABLE";
|
|
14
|
-
readonly DB_CONNECTION_REFUSED: "DB_CONNECTION_REFUSED";
|
|
15
|
-
readonly DB_TLS_FAILED: "DB_TLS_FAILED";
|
|
16
|
-
readonly DB_AUTH_FAILED: "DB_AUTH_FAILED";
|
|
17
|
-
readonly DB_VALIDATION_TIMEOUT: "DB_VALIDATION_TIMEOUT";
|
|
18
13
|
readonly RESULT_TOO_LARGE: "RESULT_TOO_LARGE";
|
|
19
14
|
readonly AUDIT_FAILED: "AUDIT_FAILED";
|
|
20
15
|
readonly SERVER_BUSY: "SERVER_BUSY";
|
package/dist/utils/formatter.js
CHANGED
|
@@ -9,11 +9,6 @@ export const ErrorCode = {
|
|
|
9
9
|
QUERY_TIMEOUT: "QUERY_TIMEOUT",
|
|
10
10
|
QUERY_CANCELLED: "QUERY_CANCELLED",
|
|
11
11
|
CONNECTION_FAILED: "CONNECTION_FAILED",
|
|
12
|
-
DB_ENDPOINT_UNREACHABLE: "DB_ENDPOINT_UNREACHABLE",
|
|
13
|
-
DB_CONNECTION_REFUSED: "DB_CONNECTION_REFUSED",
|
|
14
|
-
DB_TLS_FAILED: "DB_TLS_FAILED",
|
|
15
|
-
DB_AUTH_FAILED: "DB_AUTH_FAILED",
|
|
16
|
-
DB_VALIDATION_TIMEOUT: "DB_VALIDATION_TIMEOUT",
|
|
17
12
|
RESULT_TOO_LARGE: "RESULT_TOO_LARGE",
|
|
18
13
|
AUDIT_FAILED: "AUDIT_FAILED",
|
|
19
14
|
SERVER_BUSY: "SERVER_BUSY",
|