taurusdb-core 0.5.0-rc.3 → 0.5.0-rc.5
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 +6 -20
- package/dist/auth/sql-profile-loader/parsing.js +3 -9
- package/dist/auth/sql-profile-loader/types.d.ts +1 -3
- package/dist/config/env.js +1 -0
- package/dist/config/schema.d.ts +5 -0
- package/dist/config/schema.js +2 -1
- package/dist/engine.d.ts +3 -1
- package/dist/engine.js +4 -1
- package/dist/executor/connection-pool.js +3 -4
- package/package.json +1 -1
|
@@ -12,7 +12,8 @@ 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
|
|
15
|
+
const explicitProfileName = asString(env.TAURUSDB_SQL_DATASOURCE);
|
|
16
|
+
const profileName = explicitProfileName ?? "taurus_mcp";
|
|
16
17
|
let engine;
|
|
17
18
|
let host;
|
|
18
19
|
let port;
|
|
@@ -40,6 +41,7 @@ export function parseEnvProfile(env) {
|
|
|
40
41
|
}
|
|
41
42
|
if (!dsn &&
|
|
42
43
|
!explicitHost &&
|
|
44
|
+
!explicitProfileName &&
|
|
43
45
|
!asString(env.TAURUSDB_SQL_USER) &&
|
|
44
46
|
!asString(env.TAURUSDB_SQL_PASSWORD) &&
|
|
45
47
|
!database) {
|
|
@@ -49,23 +51,13 @@ export function parseEnvProfile(env) {
|
|
|
49
51
|
throw new Error("Failed to resolve SQL port from environment.");
|
|
50
52
|
}
|
|
51
53
|
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
|
-
}
|
|
55
54
|
passwordRef =
|
|
56
55
|
passwordRef ??
|
|
57
56
|
(Object.hasOwn(env, "TAURUSDB_SQL_PASSWORD")
|
|
58
57
|
? parseCredentialRef(env.TAURUSDB_SQL_PASSWORD, "TAURUSDB_SQL_PASSWORD")
|
|
59
58
|
: undefined);
|
|
60
|
-
if (!passwordRef) {
|
|
61
|
-
throw new Error("
|
|
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.");
|
|
59
|
+
if ((username && !passwordRef) || (!username && passwordRef)) {
|
|
60
|
+
throw new Error("SQL credentials require both username and password. Omit both to use the local database login page.");
|
|
69
61
|
}
|
|
70
62
|
const poolSize = asInteger(env.TAURUSDB_SQL_POOL_SIZE);
|
|
71
63
|
if (poolSize !== undefined && poolSize <= 0) {
|
|
@@ -77,13 +69,7 @@ export function parseEnvProfile(env) {
|
|
|
77
69
|
host,
|
|
78
70
|
port,
|
|
79
71
|
database,
|
|
80
|
-
user: {
|
|
81
|
-
username,
|
|
82
|
-
password: passwordRef,
|
|
83
|
-
},
|
|
84
|
-
mutationUser: mutationUsername && mutationPasswordRef
|
|
85
|
-
? { username: mutationUsername, password: mutationPasswordRef }
|
|
86
|
-
: undefined,
|
|
72
|
+
user: username && passwordRef ? { username, password: passwordRef } : undefined,
|
|
87
73
|
poolSize,
|
|
88
74
|
});
|
|
89
75
|
}
|
|
@@ -196,19 +196,14 @@ 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 session 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
|
-
|
|
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
|
|
204
|
+
const user = userRaw === undefined
|
|
210
205
|
? undefined
|
|
211
|
-
: parseUserCredential(
|
|
206
|
+
: parseUserCredential(userRaw, `${context}.${name}.user`);
|
|
212
207
|
const tls = parseTlsOptions(value.tls, `${context}.${name}.tls`);
|
|
213
208
|
return withRedactedToString({
|
|
214
209
|
name,
|
|
@@ -219,7 +214,6 @@ export function parseProfileRecord(name, value, context) {
|
|
|
219
214
|
instanceId,
|
|
220
215
|
nodeId,
|
|
221
216
|
user,
|
|
222
|
-
mutationUser,
|
|
223
217
|
tls,
|
|
224
218
|
poolSize,
|
|
225
219
|
});
|
|
@@ -33,10 +33,8 @@ export interface DataSourceProfile {
|
|
|
33
33
|
database?: string;
|
|
34
34
|
instanceId?: string;
|
|
35
35
|
nodeId?: string;
|
|
36
|
-
/**
|
|
36
|
+
/** Session credential used by guarded query tools and the human-gated recovery path. */
|
|
37
37
|
user?: UserCredential;
|
|
38
|
-
/** Separate credential required for mutation tools. No fallback is allowed. */
|
|
39
|
-
mutationUser?: UserCredential;
|
|
40
38
|
tls?: TlsOptions;
|
|
41
39
|
poolSize?: number;
|
|
42
40
|
toString(): string;
|
package/dist/config/env.js
CHANGED
|
@@ -161,6 +161,7 @@ export function buildRawConfigFromEnv(env) {
|
|
|
161
161
|
},
|
|
162
162
|
security: {
|
|
163
163
|
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"),
|
|
164
165
|
requireTls: parseBoolean(env.TAURUSDB_REQUIRE_TLS, "TAURUSDB_REQUIRE_TLS"),
|
|
165
166
|
approvalSecretPath: expandTildePath(readString(env.TAURUSDB_MUTATION_APPROVAL_SECRET_FILE)),
|
|
166
167
|
approvalTtlSeconds: parseInteger(env.TAURUSDB_MUTATION_APPROVAL_TTL_SECONDS, "TAURUSDB_MUTATION_APPROVAL_TTL_SECONDS"),
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -106,6 +106,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
106
106
|
}>>;
|
|
107
107
|
security: z.ZodDefault<z.ZodObject<{
|
|
108
108
|
dynamicTargetsEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
109
|
+
recycleBinRestoreEnabled: z.ZodDefault<z.ZodBoolean>;
|
|
109
110
|
requireTls: z.ZodDefault<z.ZodBoolean>;
|
|
110
111
|
approvalSecretPath: z.ZodOptional<z.ZodString>;
|
|
111
112
|
approvalTtlSeconds: z.ZodDefault<z.ZodNumber>;
|
|
@@ -113,6 +114,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
113
114
|
credentialMaxTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
114
115
|
}, "strip", z.ZodTypeAny, {
|
|
115
116
|
dynamicTargetsEnabled: boolean;
|
|
117
|
+
recycleBinRestoreEnabled: boolean;
|
|
116
118
|
requireTls: boolean;
|
|
117
119
|
approvalTtlSeconds: number;
|
|
118
120
|
credentialIdleTtlMinutes: number;
|
|
@@ -120,6 +122,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
120
122
|
approvalSecretPath?: string | undefined;
|
|
121
123
|
}, {
|
|
122
124
|
dynamicTargetsEnabled?: boolean | undefined;
|
|
125
|
+
recycleBinRestoreEnabled?: boolean | undefined;
|
|
123
126
|
requireTls?: boolean | undefined;
|
|
124
127
|
approvalSecretPath?: string | undefined;
|
|
125
128
|
approvalTtlSeconds?: number | undefined;
|
|
@@ -362,6 +365,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
362
365
|
};
|
|
363
366
|
security: {
|
|
364
367
|
dynamicTargetsEnabled: boolean;
|
|
368
|
+
recycleBinRestoreEnabled: boolean;
|
|
365
369
|
requireTls: boolean;
|
|
366
370
|
approvalTtlSeconds: number;
|
|
367
371
|
credentialIdleTtlMinutes: number;
|
|
@@ -454,6 +458,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
454
458
|
} | undefined;
|
|
455
459
|
security?: {
|
|
456
460
|
dynamicTargetsEnabled?: boolean | undefined;
|
|
461
|
+
recycleBinRestoreEnabled?: boolean | undefined;
|
|
457
462
|
requireTls?: boolean | undefined;
|
|
458
463
|
approvalSecretPath?: string | undefined;
|
|
459
464
|
approvalTtlSeconds?: number | undefined;
|
package/dist/config/schema.js
CHANGED
|
@@ -22,7 +22,8 @@ const AuditSchema = z
|
|
|
22
22
|
.default({});
|
|
23
23
|
const SecuritySchema = z
|
|
24
24
|
.object({
|
|
25
|
-
dynamicTargetsEnabled: z.boolean().default(
|
|
25
|
+
dynamicTargetsEnabled: z.boolean().default(true),
|
|
26
|
+
recycleBinRestoreEnabled: z.boolean().default(true),
|
|
26
27
|
requireTls: z.boolean().default(true),
|
|
27
28
|
approvalSecretPath: z.string().min(1).optional(),
|
|
28
29
|
approvalTtlSeconds: z.number().int().positive().max(3600).default(300),
|
package/dist/engine.d.ts
CHANGED
|
@@ -5,11 +5,12 @@ import type { CapabilitySnapshot, FeatureMatrix, KernelInfo } from "./capability
|
|
|
5
5
|
import { type Config } from "./config/index.js";
|
|
6
6
|
import type { DatasourceResolveInput, DatasourceResolver, SessionContext } from "./context/session-context.js";
|
|
7
7
|
import { type ConnectionPool } from "./executor/connection-pool.js";
|
|
8
|
-
import { type CancelResult, type ExplainResult, type QueryResult, type QueryStatus, type ReadonlyOptions, type SqlExecutor } from "./executor/sql-executor.js";
|
|
8
|
+
import { type CancelResult, type ExplainResult, type MutationOptions, type MutationResult, type QueryResult, type QueryStatus, type ReadonlyOptions, type SqlExecutor } from "./executor/sql-executor.js";
|
|
9
9
|
import { type ConfirmationStore, type ConfirmationRequest, type ConfirmationValidationResult } from "./safety/confirmation-store.js";
|
|
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 { RestoreRecycleBinTableInput } from "./taurus/recycle-bin.js";
|
|
13
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";
|
|
14
15
|
import { type SlowSqlSource } from "./diagnostics/slow-sql-source.js";
|
|
15
16
|
import { type MetricsSource } from "./diagnostics/metrics-source.js";
|
|
@@ -66,6 +67,7 @@ export declare class TaurusDBEngine {
|
|
|
66
67
|
executeReadonly(sql: string, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
67
68
|
flashbackQuery(input: FlashbackInput, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
68
69
|
listRecycleBin(ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
70
|
+
restoreRecycleBinTable(input: RestoreRecycleBinTableInput, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
69
71
|
getQueryStatus(queryId: string): Promise<QueryStatus>;
|
|
70
72
|
cancelQuery(queryId: string): Promise<CancelResult>;
|
|
71
73
|
issueConfirmation(input: IssueConfirmationInput): Promise<ConfirmationRequest>;
|
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, validateConfirmation, } from "./engine/runtime.js";
|
|
21
|
+
import { cancelQuery, close, 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()) {
|
|
@@ -251,6 +251,9 @@ export class TaurusDBEngine {
|
|
|
251
251
|
async listRecycleBin(ctx, opts) {
|
|
252
252
|
return listRecycleBin(this, ctx, opts);
|
|
253
253
|
}
|
|
254
|
+
async restoreRecycleBinTable(input, ctx, opts) {
|
|
255
|
+
return restoreRecycleBinTable(this, input, ctx, opts);
|
|
256
|
+
}
|
|
254
257
|
async getQueryStatus(queryId) {
|
|
255
258
|
return getQueryStatus(this, queryId);
|
|
256
259
|
}
|
|
@@ -39,11 +39,10 @@ async function resolveTls(tls, secretResolver, host, requireTls) {
|
|
|
39
39
|
}
|
|
40
40
|
return resolved;
|
|
41
41
|
}
|
|
42
|
-
function selectCredential(profile,
|
|
43
|
-
const credential =
|
|
42
|
+
function selectCredential(profile, _mode) {
|
|
43
|
+
const credential = profile.user;
|
|
44
44
|
if (!credential) {
|
|
45
|
-
|
|
46
|
-
throw new ConnectionPoolError(`Datasource "${profile.name}" does not define ${credentialKind} SQL credentials. Configure a dedicated ${credentialKind} database username and password reference.`);
|
|
45
|
+
throw new ConnectionPoolError(`Datasource "${profile.name}" has no active SQL credential session. Select a TaurusDB instance and open the returned local login URL, or call begin_sql_login.`);
|
|
47
46
|
}
|
|
48
47
|
return credential;
|
|
49
48
|
}
|