@fadhilp/stateql 0.10.0 → 0.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.
@@ -5,7 +5,7 @@ import { writeFileSync } from "node:fs";
5
5
  import { basename, resolve } from "node:path";
6
6
  import { env } from "node:process";
7
7
  import { AdapterExecutionError, AdapterWriteError, BatchWriteError, createAdapter, createAdapterContext, } from "./adapters.js";
8
- import { confidence, credentialSource, databaseIdentity, databaseUrlHasSecret, detectDriver, isEnvironmentName, mongoDatabaseName, redisDatabaseName, normalizeSqliteSource, validateCredentialRef, validateProfileName, version, } from "./connection.js";
8
+ import { confidence, credentialSource, databaseIdentity, databaseUrlHasSecret, detectDriver, isEnvironmentName, injectPassword, mongoDatabaseName, redisDatabaseName, normalizeSqliteSource, validateCredentialRef, validatePasswordReferenceTarget, validateProfileName, version, } from "./connection.js";
9
9
  import { asStateQLError, CredentialResolutionError, StateQLError, } from "./errors.js";
10
10
  import { analyzeMongoWriteSafety, deserializeMongoWriteCommand, serializeMongoCommand, validateMongoReadCommand, validateMongoWriteCommand, MongoAdapter, } from "./mongodb.js";
11
11
  import { deserializeRedisCommand, RedisAdapter, serializeRedisCommand, validateRedisReadCommand, validateRedisWriteCommand, } from "./redis.js";
@@ -18,6 +18,8 @@ const DEFAULT_SNAPSHOT_HISTORY_LIMIT = 50;
18
18
  const MAX_SNAPSHOT_HISTORY_LIMIT = 100;
19
19
  const DEFAULT_CREDENTIAL_RESOLUTION_TIMEOUT_MS = 120_000;
20
20
  export class StateQL {
21
+ /** Runtime contract marker for passwordRef/password_ref support. */
22
+ static passwordReferenceVersion = 1;
21
23
  static forActor(options) {
22
24
  if (!options.actor.trim()) {
23
25
  throw new StateQLError("INVALID_COMMAND", "Actor ID is required.");
@@ -112,7 +114,13 @@ export class StateQL {
112
114
  if (sourceCount !== 1) {
113
115
  throw new StateQLError("INVALID_COMMAND", "Use exactly one connection target, profile, secret environment variable, or credential reference.");
114
116
  }
115
- const implicitProfile = !options.profile && !options.secretEnv && !options.credentialRef && target
117
+ if (options.passwordRef !== undefined &&
118
+ (target === undefined || options.profile !== undefined ||
119
+ options.secretEnv !== undefined || options.credentialRef !== undefined)) {
120
+ throw new StateQLError("INVALID_COMMAND", "A password reference requires a literal remote connection target.");
121
+ }
122
+ const implicitProfile = !options.profile && !options.secretEnv && !options.credentialRef &&
123
+ options.passwordRef === undefined && target
116
124
  ? this.store.getProfile(target)
117
125
  : undefined;
118
126
  const profile = options.profile
@@ -122,18 +130,27 @@ export class StateQL {
122
130
  throw new StateQLError("CONNECTION_NOT_FOUND", `Profile "${options.profile}" was not found.`, { suggestedAction: "Run stql profile list." });
123
131
  }
124
132
  if (profile &&
125
- [profile.target, profile.secret_env, profile.credential_ref]
126
- .filter((value) => value !== null).length !== 1) {
127
- throw new StateQLError("STATE_CORRUPTED", `Profile "${profile.name}" does not have exactly one connection source.`);
133
+ ([profile.target, profile.secret_env, profile.credential_ref]
134
+ .filter((value) => value !== null).length !== 1 ||
135
+ (profile.password_ref !== null && profile.target === null))) {
136
+ throw new StateQLError("STATE_CORRUPTED", `Profile "${profile.name}" has an invalid connection source.`);
128
137
  }
129
138
  const resolvedTarget = profile?.target ?? target;
130
139
  const secretEnv = options.secretEnv ?? profile?.secret_env ?? undefined;
131
140
  const credentialRef = options.credentialRef ?? profile?.credential_ref ?? undefined;
141
+ const passwordRef = options.passwordRef ?? profile?.password_ref ?? undefined;
132
142
  if (secretEnv !== undefined && !isEnvironmentName(secretEnv)) {
133
143
  throw new StateQLError("INVALID_COMMAND", "Secret environment variable name is invalid.");
134
144
  }
135
145
  if (credentialRef !== undefined)
136
146
  validateCredentialRef(credentialRef);
147
+ if (passwordRef !== undefined) {
148
+ validateCredentialRef(passwordRef);
149
+ if (!resolvedTarget) {
150
+ throw new StateQLError("INVALID_COMMAND", "A password reference requires a literal remote connection target.");
151
+ }
152
+ validatePasswordReferenceTarget(resolvedTarget);
153
+ }
137
154
  const credentialReference = secretEnv ?? credentialRef;
138
155
  const credentialReferenceSource = secretEnv !== undefined
139
156
  ? "secret_env"
@@ -141,50 +158,65 @@ export class StateQL {
141
158
  const readOnly = options.readOnly ??
142
159
  (profile ? Boolean(profile.read_only) : true);
143
160
  const context = this.executionContext(options);
144
- const secret = credentialReference && credentialReferenceSource
145
- ? await this.resolveCredential(credentialReference, credentialReferenceSource, session, "connect", readOnly ? "read" : "write", context, {
161
+ let adapterSource;
162
+ let driver;
163
+ if (passwordRef !== undefined) {
164
+ const password = await this.resolveCredential(passwordRef, "password_ref", session, "connect", readOnly ? "read" : "write", context, {
146
165
  ...(profile ? { profile: { name: profile.name } } : {}),
147
166
  requestedReadOnly: readOnly,
148
- })
149
- : resolvedTarget;
150
- if (!secret) {
151
- throw new StateQLError("INVALID_COMMAND", "Connection target is required.");
152
- }
153
- const resolvedSource = credentialReferenceSource
154
- ? credentialSource(secret, undefined, credentialReferenceSource)
155
- : { driver: detectDriver(secret), source: secret };
156
- const { driver } = resolvedSource;
157
- if (driver !== "sqlite" &&
158
- !credentialReference &&
159
- databaseUrlHasSecret(secret)) {
160
- throw new StateQLError("PERMISSION_DENIED", `Credential-bearing ${databaseDisplayName(driver)} URLs must use --env or --credential-ref.`, {
161
- suggestedAction: "Use an environment variable or trusted host credential reference.",
162
- });
167
+ }, resolvedTarget);
168
+ ({ driver, source: adapterSource } = injectPassword(resolvedTarget, password));
163
169
  }
164
- const adapterSource = credentialReferenceSource
165
- ? resolvedSource.source
166
- : driver === "sqlite" ? normalizeSqliteSource(secret) : secret;
167
- const source = driver === "sqlite"
168
- ? adapterSource
169
- : credentialReferenceSource
170
- ? redact(secret)
171
- : adapterSource;
170
+ else {
171
+ const secret = credentialReference && credentialReferenceSource
172
+ ? await this.resolveCredential(credentialReference, credentialReferenceSource, session, "connect", readOnly ? "read" : "write", context, {
173
+ ...(profile ? { profile: { name: profile.name } } : {}),
174
+ requestedReadOnly: readOnly,
175
+ })
176
+ : resolvedTarget;
177
+ if (!secret) {
178
+ throw new StateQLError("INVALID_COMMAND", "Connection target is required.");
179
+ }
180
+ const resolvedSource = credentialReferenceSource
181
+ ? credentialSource(secret, undefined, credentialReferenceSource)
182
+ : { driver: detectDriver(secret), source: secret };
183
+ driver = resolvedSource.driver;
184
+ if (driver !== "sqlite" &&
185
+ !credentialReference &&
186
+ databaseUrlHasSecret(secret)) {
187
+ throw new StateQLError("PERMISSION_DENIED", `Credential-bearing ${databaseDisplayName(driver)} URLs must use --env or --credential-ref.`, {
188
+ suggestedAction: "Use an environment variable or trusted host credential reference.",
189
+ });
190
+ }
191
+ adapterSource = credentialReferenceSource
192
+ ? resolvedSource.source
193
+ : driver === "sqlite" ? normalizeSqliteSource(secret) : secret;
194
+ }
195
+ const persistedSource = passwordRef !== undefined
196
+ ? resolvedTarget
197
+ : driver === "sqlite"
198
+ ? adapterSource
199
+ : credentialReferenceSource
200
+ ? redact(adapterSource)
201
+ : adapterSource;
202
+ const identitySource = passwordRef !== undefined ? resolvedTarget : adapterSource;
172
203
  const databaseName = driver === "sqlite"
173
204
  ? basename(adapterSource)
174
205
  : driver === "mongodb"
175
- ? mongoDatabaseName(adapterSource)
206
+ ? mongoDatabaseName(identitySource)
176
207
  : driver === "redis"
177
- ? redisDatabaseName(adapterSource)
178
- : new URL(secret).pathname.replace(/^\//, "") || driver;
208
+ ? redisDatabaseName(identitySource)
209
+ : new URL(identitySource).pathname.replace(/^\//, "") || driver;
179
210
  const draft = {
180
211
  id: "pending",
181
212
  session_id: session.id,
182
213
  name: options.name ?? profile?.name ?? databaseName,
183
214
  driver,
184
215
  database_name: databaseName,
185
- source,
216
+ source: persistedSource,
186
217
  secret_env: secretEnv ?? null,
187
218
  credential_ref: credentialRef ?? null,
219
+ password_ref: passwordRef ?? null,
188
220
  read_only: readOnly ? 1 : 0,
189
221
  version: 0,
190
222
  created_at: this.now().toISOString(),
@@ -212,9 +244,10 @@ export class StateQL {
212
244
  name: draft.name,
213
245
  driver,
214
246
  databaseName,
215
- source,
247
+ source: persistedSource,
216
248
  ...(secretEnv ? { secretEnv } : {}),
217
249
  ...(credentialRef ? { credentialRef } : {}),
250
+ ...(passwordRef !== undefined ? { passwordRef } : {}),
218
251
  readOnly,
219
252
  });
220
253
  if (!connection) {
@@ -223,6 +256,8 @@ export class StateQL {
223
256
  return {
224
257
  data: {
225
258
  connection_id: connection.id,
259
+ alias: connection.alias,
260
+ display_alias: connection.alias,
226
261
  driver,
227
262
  database: databaseName,
228
263
  name: connection.name,
@@ -248,12 +283,14 @@ export class StateQL {
248
283
  target,
249
284
  secretEnv: options.secretEnv,
250
285
  credentialRef: options.credentialRef,
286
+ passwordRef: options.passwordRef,
251
287
  });
252
288
  const profile = this.store.addProfile({
253
289
  name,
254
290
  target: source.target ?? undefined,
255
291
  secretEnv: source.secretEnv ?? undefined,
256
292
  credentialRef: source.credentialRef ?? undefined,
293
+ passwordRef: source.passwordRef ?? undefined,
257
294
  readOnly: options.readOnly ?? true,
258
295
  });
259
296
  return {
@@ -270,22 +307,32 @@ export class StateQL {
270
307
  if (!existing)
271
308
  throw new StateQLError("CONNECTION_NOT_FOUND", `Profile "${name}" was not found.`);
272
309
  if (!changes || typeof changes !== "object" || Array.isArray(changes) ||
273
- Object.keys(changes).some((key) => !["target", "secretEnv", "credentialRef", "readOnly"].includes(key))) {
310
+ Object.keys(changes).some((key) => !["target", "secretEnv", "credentialRef", "passwordRef", "readOnly"].includes(key))) {
274
311
  throw new StateQLError("INVALID_COMMAND", "Profile update contains unknown fields.");
275
312
  }
276
313
  if (changes.readOnly !== undefined && typeof changes.readOnly !== "boolean")
277
314
  throw new StateQLError("INVALID_COMMAND", "Profile readOnly must be boolean.");
278
315
  const changesSource = Object.hasOwn(changes, "target") || Object.hasOwn(changes, "secretEnv") || Object.hasOwn(changes, "credentialRef");
279
- if (!changesSource && changes.readOnly === undefined)
316
+ const changesPassword = Object.hasOwn(changes, "passwordRef");
317
+ if (!changesSource && !changesPassword && changes.readOnly === undefined)
280
318
  throw new StateQLError("INVALID_COMMAND", "Profile update has no changes.");
281
- const source = changesSource
282
- ? validatedProfileSource({ target: changes.target ?? undefined, secretEnv: changes.secretEnv ?? undefined, credentialRef: changes.credentialRef ?? undefined })
283
- : { target: existing.target, secretEnv: existing.secret_env, credentialRef: existing.credential_ref };
319
+ const targetSource = changesSource ? changes.target ?? undefined : existing.target ?? undefined;
320
+ const source = validatedProfileSource({
321
+ target: targetSource,
322
+ secretEnv: changesSource ? changes.secretEnv ?? undefined : existing.secret_env ?? undefined,
323
+ credentialRef: changesSource ? changes.credentialRef ?? undefined : existing.credential_ref ?? undefined,
324
+ passwordRef: changesPassword
325
+ ? changes.passwordRef ?? undefined
326
+ : !changesSource || targetSource === existing.target
327
+ ? existing.password_ref ?? undefined
328
+ : undefined,
329
+ });
284
330
  const profile = this.store.updateProfile({
285
331
  name,
286
332
  target: source.target,
287
333
  secretEnv: source.secretEnv,
288
334
  credentialRef: source.credentialRef,
335
+ passwordRef: source.passwordRef,
289
336
  readOnly: changes.readOnly ?? Boolean(existing.read_only),
290
337
  });
291
338
  if (!profile)
@@ -368,6 +415,8 @@ export class StateQL {
368
415
  connection: connection
369
416
  ? {
370
417
  connection_id: connection.id,
418
+ alias: connection.alias,
419
+ display_alias: connection.alias,
371
420
  name: connection.name,
372
421
  status: "connected",
373
422
  driver: connection.driver,
@@ -1707,7 +1756,7 @@ export class StateQL {
1707
1756
  const planParameters = compiled?.params ?? (nativePlan || tableUpdates
1708
1757
  ? undefined
1709
1758
  : parseJson(plan.parameters, `plan "${plan.id}" parameters`, isSqlParameters));
1710
- const claimToken = this.store.nextId("claim");
1759
+ const claimToken = this.store.randomId("claim");
1711
1760
  const claimed = this.store.claimPlan(plan.id, session.id, this.actorId, claimToken);
1712
1761
  if (!claimed) {
1713
1762
  throw new StateQLError("STALE_PLAN", "Plan is already being applied.");
@@ -1896,6 +1945,7 @@ export class StateQL {
1896
1945
  readOnly: command.read_only,
1897
1946
  secretEnv: command.secret_env,
1898
1947
  credentialRef: command.credential_ref,
1948
+ passwordRef: command.password_ref ?? undefined,
1899
1949
  profile: command.profile,
1900
1950
  timeoutMs: command.timeout_ms,
1901
1951
  });
@@ -1908,12 +1958,14 @@ export class StateQL {
1908
1958
  readOnly: command.read_only ?? true,
1909
1959
  secretEnv: command.secret_env,
1910
1960
  credentialRef: command.credential_ref,
1961
+ passwordRef: command.password_ref ?? undefined,
1911
1962
  });
1912
1963
  case "profile.update":
1913
1964
  return this.updateProfile(batchString(command.name, "name"), {
1914
1965
  ...(command.target !== undefined ? { target: command.target } : {}),
1915
1966
  ...(command.secret_env !== undefined ? { secretEnv: command.secret_env } : {}),
1916
1967
  ...(command.credential_ref !== undefined ? { credentialRef: command.credential_ref } : {}),
1968
+ ...(command.password_ref !== undefined ? { passwordRef: command.password_ref } : {}),
1917
1969
  ...(command.read_only !== undefined ? { readOnly: command.read_only } : {}),
1918
1970
  });
1919
1971
  case "profile.list":
@@ -2714,6 +2766,28 @@ export class StateQL {
2714
2766
  throw new StateQLError("PERMISSION_DENIED", `Actor "${this.actorId}" is not attached to session "${session.name}".`);
2715
2767
  }
2716
2768
  async resolveConnectionSource(connection, session, operation, access, context) {
2769
+ const references = [connection.secret_env, connection.credential_ref, connection.password_ref]
2770
+ .filter((value) => value !== null);
2771
+ if (references.length > 1) {
2772
+ throw new StateQLError("STATE_CORRUPTED", "Connection has ambiguous credential references.");
2773
+ }
2774
+ if (connection.password_ref !== null) {
2775
+ validateCredentialRef(connection.password_ref);
2776
+ const driver = validatePasswordReferenceTarget(connection.source);
2777
+ if (driver !== connection.driver) {
2778
+ throw new StateQLError("STATE_CORRUPTED", "Password-reference target driver does not match the stored connection.");
2779
+ }
2780
+ const password = await this.resolveCredential(connection.password_ref, "password_ref", session, operation, access, context, {
2781
+ connection: {
2782
+ id: connection.id,
2783
+ name: connection.name,
2784
+ driver: connection.driver,
2785
+ database: connection.database_name,
2786
+ readOnly: Boolean(connection.read_only),
2787
+ },
2788
+ }, connection.source);
2789
+ return injectPassword(connection.source, password).source;
2790
+ }
2717
2791
  const reference = connection.secret_env ?? connection.credential_ref;
2718
2792
  if (!reference)
2719
2793
  return connection.source;
@@ -2731,7 +2805,7 @@ export class StateQL {
2731
2805
  });
2732
2806
  return credentialSource(value, connection.driver, source).source;
2733
2807
  }
2734
- async resolveCredential(reference, source, session, operation, access, context, details = {}) {
2808
+ async resolveCredential(reference, source, session, operation, access, context, details = {}, passwordTarget) {
2735
2809
  const resolver = this.credentialResolver;
2736
2810
  const credentialContext = createAdapterContext(this.credentialTimeoutMs, context.signal);
2737
2811
  let value;
@@ -2746,9 +2820,8 @@ export class StateQL {
2746
2820
  value = env[reference];
2747
2821
  }
2748
2822
  else {
2749
- const request = {
2823
+ const baseRequest = {
2750
2824
  reference,
2751
- source,
2752
2825
  actorId: this.actorId,
2753
2826
  session: { id: session.id, name: session.name },
2754
2827
  operation,
@@ -2756,6 +2829,9 @@ export class StateQL {
2756
2829
  ...(context.signal ? { signal: context.signal } : {}),
2757
2830
  ...details,
2758
2831
  };
2832
+ const request = source === "password_ref"
2833
+ ? { ...baseRequest, source, target: passwordTarget }
2834
+ : { ...baseRequest, source };
2759
2835
  try {
2760
2836
  value = await resolveCredentialBeforeDeadline(resolver, request, credentialContext);
2761
2837
  }
@@ -2763,7 +2839,7 @@ export class StateQL {
2763
2839
  throw credentialStateQLError(reference, error);
2764
2840
  }
2765
2841
  }
2766
- if (!value) {
2842
+ if (value === undefined || (source !== "password_ref" && value === "")) {
2767
2843
  throw credentialStateQLError(reference, new CredentialResolutionError("unavailable"));
2768
2844
  }
2769
2845
  context.deadline = Date.now() + (context.timeoutMs ?? this.timeoutMs);
@@ -2840,8 +2916,8 @@ export class StateQL {
2840
2916
  const category = historyCategory(command);
2841
2917
  const internal = commandContext?.internal ?? false;
2842
2918
  let session = this.store.ensureSession(this.sessionName);
2843
- const commandId = this.store.nextId("cmd");
2844
2919
  if (!this.store.isSessionMember(session.id, this.actorId)) {
2920
+ const commandId = this.store.randomId("cmd");
2845
2921
  const error = new StateQLError("PERMISSION_DENIED", `Actor "${this.actorId}" is not attached to session "${session.name}".`);
2846
2922
  return {
2847
2923
  ok: false,
@@ -2857,8 +2933,7 @@ export class StateQL {
2857
2933
  const result = await action(session);
2858
2934
  const responseSession = result.session ?? session;
2859
2935
  const sqlText = resolveHistorySql(historySql);
2860
- this.store.addHistory({
2861
- id: commandId,
2936
+ const history = this.store.addHistory({
2862
2937
  sessionId: session.id,
2863
2938
  actorId: this.actorId,
2864
2939
  origin,
@@ -2874,7 +2949,7 @@ export class StateQL {
2874
2949
  });
2875
2950
  return {
2876
2951
  ok: true,
2877
- command_id: commandId,
2952
+ command_id: history.id,
2878
2953
  session_id: responseSession.id,
2879
2954
  data: result.data,
2880
2955
  warnings: result.warnings ?? [],
@@ -2892,8 +2967,7 @@ export class StateQL {
2892
2967
  catch (error) {
2893
2968
  const stateqlError = asStateQLError(error);
2894
2969
  const sqlText = resolveHistorySql(historySql);
2895
- this.store.addHistory({
2896
- id: commandId,
2970
+ const history = this.store.addHistory({
2897
2971
  sessionId: session.id,
2898
2972
  actorId: this.actorId,
2899
2973
  origin,
@@ -2909,7 +2983,7 @@ export class StateQL {
2909
2983
  });
2910
2984
  return {
2911
2985
  ok: false,
2912
- command_id: commandId,
2986
+ command_id: history.id,
2913
2987
  session_id: session.id,
2914
2988
  error: stateqlError.details,
2915
2989
  meta: {
@@ -3210,7 +3284,23 @@ function credentialStateQLError(reference, error) {
3210
3284
  return new StateQLError("CREDENTIAL_RESOLUTION_FAILED", `Credential reference "${reference}" could not be resolved.`, { retryable: true });
3211
3285
  }
3212
3286
  function safeCredentialErrorMessage(error, source) {
3213
- return redact(errorMessage(error).split(source).join("[credential redacted]"))
3287
+ let message = errorMessage(error).split(source).join("[credential redacted]");
3288
+ const authority = /^[a-z][a-z\d+.-]*:\/\/([^/?#]*)/i.exec(source)?.[1];
3289
+ if (authority) {
3290
+ const at = authority.lastIndexOf("@");
3291
+ const colon = at < 0 ? -1 : authority.slice(0, at).indexOf(":");
3292
+ const password = colon < 0 ? "" : authority.slice(colon + 1, at);
3293
+ const secrets = new Set([password]);
3294
+ try {
3295
+ secrets.add(decodeURIComponent(password));
3296
+ }
3297
+ catch { /* malformed values stay encoded */ }
3298
+ for (const secret of secrets) {
3299
+ if (secret)
3300
+ message = message.split(secret).join("[credential redacted]");
3301
+ }
3302
+ }
3303
+ return redact(message)
3214
3304
  .replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^\s\/@]+(?::[^\s\/@]*)?@/giu, "$1***@");
3215
3305
  }
3216
3306
  function executionTimeout(value, name = "timeoutMs") {
@@ -3232,15 +3322,27 @@ function validatedProfileSource(input) {
3232
3322
  throw new StateQLError("INVALID_COMMAND", "Secret environment variable name is invalid.");
3233
3323
  if (input.credentialRef !== undefined)
3234
3324
  validateCredentialRef(input.credentialRef);
3325
+ if (input.passwordRef !== undefined)
3326
+ validateCredentialRef(input.passwordRef);
3235
3327
  let target = input.target ?? null;
3328
+ if (input.passwordRef !== undefined && target === null) {
3329
+ throw new StateQLError("INVALID_COMMAND", "A password reference requires a literal remote profile target.");
3330
+ }
3236
3331
  if (target) {
3237
- const driver = detectDriver(target);
3238
- if (driver !== "sqlite" && databaseUrlHasSecret(target))
3332
+ const driver = input.passwordRef !== undefined
3333
+ ? validatePasswordReferenceTarget(target)
3334
+ : detectDriver(target);
3335
+ if (input.passwordRef === undefined && driver !== "sqlite" && databaseUrlHasSecret(target))
3239
3336
  throw new StateQLError("PERMISSION_DENIED", `Credential-bearing ${databaseDisplayName(driver)} URLs must use --env or --credential-ref.`);
3240
3337
  if (driver === "sqlite")
3241
3338
  target = normalizeSqliteSource(target);
3242
3339
  }
3243
- return { target, secretEnv: input.secretEnv ?? null, credentialRef: input.credentialRef ?? null };
3340
+ return {
3341
+ target,
3342
+ secretEnv: input.secretEnv ?? null,
3343
+ credentialRef: input.credentialRef ?? null,
3344
+ passwordRef: input.passwordRef ?? null,
3345
+ };
3244
3346
  }
3245
3347
  function historyCategory(command) {
3246
3348
  if (["query", "exec", "plan", "apply", "mongo.query", "mongo.exec", "mongo.plan", "redis.query", "redis.exec", "redis.plan", "filter"].includes(command))
@@ -11,6 +11,7 @@ export interface SessionRecord {
11
11
  }
12
12
  export interface ConnectionRecord {
13
13
  id: string;
14
+ alias?: string;
14
15
  session_id: string;
15
16
  name: string;
16
17
  driver: Driver;
@@ -18,6 +19,7 @@ export interface ConnectionRecord {
18
19
  source: string;
19
20
  secret_env: string | null;
20
21
  credential_ref: string | null;
22
+ password_ref: string | null;
21
23
  read_only: number;
22
24
  version: number;
23
25
  created_at: string;
@@ -27,6 +29,7 @@ export interface ProfileRecord {
27
29
  target: string | null;
28
30
  secret_env: string | null;
29
31
  credential_ref: string | null;
32
+ password_ref: string | null;
30
33
  read_only: number;
31
34
  created_at: string;
32
35
  updated_at: string;
@@ -125,7 +128,8 @@ export declare class StateStore {
125
128
  private closed;
126
129
  constructor(home: string, now: () => Date, maxStateBytes?: number);
127
130
  close(): void;
128
- nextId(prefix: string): string;
131
+ randomId(prefix: string): string;
132
+ private insertWithRandomId;
129
133
  ensureSession(name?: string): SessionRecord;
130
134
  bootstrapSession(name: string, actorId: string, ensureLegacyMembership: boolean): SessionRecord;
131
135
  createSession(name: string): SessionRecord;
@@ -143,6 +147,7 @@ export declare class StateStore {
143
147
  target?: string;
144
148
  secretEnv?: string;
145
149
  credentialRef?: string;
150
+ passwordRef?: string;
146
151
  readOnly: boolean;
147
152
  }): ProfileRecord;
148
153
  updateProfile(input: {
@@ -150,6 +155,7 @@ export declare class StateStore {
150
155
  target: string | null;
151
156
  secretEnv: string | null;
152
157
  credentialRef: string | null;
158
+ passwordRef: string | null;
153
159
  readOnly: boolean;
154
160
  }): ProfileRecord | undefined;
155
161
  getProfile(name: string): ProfileRecord | undefined;
@@ -164,8 +170,11 @@ export declare class StateStore {
164
170
  source: string;
165
171
  secretEnv?: string;
166
172
  credentialRef?: string;
173
+ passwordRef?: string;
167
174
  readOnly: boolean;
168
175
  }): ConnectionRecord | undefined;
176
+ private allocateConnectionAlias;
177
+ private backfillConnectionAliases;
169
178
  getConnection(id: string): ConnectionRecord | undefined;
170
179
  activeConnection(session: SessionRecord): ConnectionRecord | undefined;
171
180
  disconnect(sessionId: string, actorId: string): boolean;