ydb-qdrant 9.0.3 → 9.1.1

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/README.md CHANGED
@@ -54,7 +54,16 @@ npm install
54
54
  ```
55
55
 
56
56
  ## Configure credentials
57
- The server uses `getCredentialsFromEnv()` and supports these env vars (first match wins):
57
+ The server supports explicit programmatic `authService` in the npm API. Without it, env-based credentials are used:
58
+
59
+ - Static username/password credentials (durable local YDB)
60
+ ```bash
61
+ export YDB_STATIC_CREDENTIALS_USER=qdrantapp
62
+ export YDB_STATIC_CREDENTIALS_PASSWORD_FILE=/run/secrets/qdrantapp.password
63
+ ```
64
+ `YDB_STATIC_CREDENTIALS_PASSWORD` is supported only as a fallback when a password file is not set. `YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT` can override the auth endpoint; otherwise the YDB endpoint is used. For private CA TLS, set `YDB_SSL_ROOT_CERTIFICATES_FILE`.
65
+
66
+ The remaining YDB SDK env credentials are resolved by `getCredentialsFromEnv()`:
58
67
 
59
68
  - Service account key file (recommended)
60
69
  ```bash
@@ -1,6 +1,11 @@
1
1
  import "dotenv/config";
2
2
  export declare const YDB_QDRANT_ENDPOINT: string;
3
3
  export declare const YDB_QDRANT_DATABASE: string;
4
+ export declare const YDB_STATIC_CREDENTIALS_USER: string;
5
+ export declare const YDB_STATIC_CREDENTIALS_PASSWORD_FILE: string;
6
+ export declare const YDB_STATIC_CREDENTIALS_PASSWORD: string;
7
+ export declare const YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT: string;
8
+ export declare const YDB_SSL_ROOT_CERTIFICATES_FILE: string;
4
9
  export declare const LEGACY_YDB_ENDPOINT: string;
5
10
  export declare const LEGACY_YDB_DATABASE: string;
6
11
  export declare const YDB_ENDPOINT: string;
@@ -2,6 +2,11 @@ import "dotenv/config";
2
2
  import { parseBooleanEnv, parseIntegerEnv } from "../utils/EnvParsers.js";
3
3
  export const YDB_QDRANT_ENDPOINT = process.env.YDB_QDRANT_ENDPOINT?.trim() ?? "";
4
4
  export const YDB_QDRANT_DATABASE = process.env.YDB_QDRANT_DATABASE?.trim() ?? "";
5
+ export const YDB_STATIC_CREDENTIALS_USER = process.env.YDB_STATIC_CREDENTIALS_USER?.trim() ?? "";
6
+ export const YDB_STATIC_CREDENTIALS_PASSWORD_FILE = process.env.YDB_STATIC_CREDENTIALS_PASSWORD_FILE?.trim() ?? "";
7
+ export const YDB_STATIC_CREDENTIALS_PASSWORD = process.env.YDB_STATIC_CREDENTIALS_PASSWORD ?? "";
8
+ export const YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT = process.env.YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT?.trim() ?? "";
9
+ export const YDB_SSL_ROOT_CERTIFICATES_FILE = process.env.YDB_SSL_ROOT_CERTIFICATES_FILE?.trim() ?? "";
5
10
  export const LEGACY_YDB_ENDPOINT = process.env.YDB_ENDPOINT?.trim() ?? "";
6
11
  export const LEGACY_YDB_DATABASE = process.env.YDB_DATABASE?.trim() ?? "";
7
12
  export const YDB_ENDPOINT = YDB_QDRANT_ENDPOINT;
@@ -1,8 +1,10 @@
1
1
  import { createRequire } from "module";
2
- import { SESSION_POOL_MIN_SIZE, SESSION_POOL_MAX_SIZE, SESSION_KEEPALIVE_PERIOD_MS, STARTUP_PROBE_SESSION_TIMEOUT_MS, YDB_SESSION_RETRY_MAX_RETRIES, TABLE_SESSION_TIMEOUT_MS, resolveYdbConnectionConfig, } from "../config/env.js";
2
+ import { readFileSync } from "fs";
3
+ import { dirname, join } from "path";
4
+ import { SESSION_POOL_MIN_SIZE, SESSION_POOL_MAX_SIZE, SESSION_KEEPALIVE_PERIOD_MS, STARTUP_PROBE_SESSION_TIMEOUT_MS, YDB_SESSION_RETRY_MAX_RETRIES, TABLE_SESSION_TIMEOUT_MS, YDB_SSL_ROOT_CERTIFICATES_FILE, YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT, YDB_STATIC_CREDENTIALS_PASSWORD, YDB_STATIC_CREDENTIALS_PASSWORD_FILE, YDB_STATIC_CREDENTIALS_USER, resolveYdbConnectionConfig, } from "../config/env.js";
3
5
  import { logger } from "../logging/logger.js";
4
6
  const require = createRequire(import.meta.url);
5
- const { Driver, getCredentialsFromEnv, Types, TypedValues, TableDescription, Column, TableIndex, AlterTableDescription, ExecuteQuerySettings, BulkUpsertSettings, OperationParams, Ydb, } = require("ydb-sdk");
7
+ const { Driver, getCredentialsFromEnv, Types, TypedValues, TableDescription, Column, TableIndex, AlterTableDescription, ExecuteQuerySettings, BulkUpsertSettings, OperationParams, StaticCredentialsAuthService, getDefaultLogger, Ydb, } = require("ydb-sdk");
6
8
  export { Types, TypedValues, TableDescription, Column, TableIndex, AlterTableDescription, ExecuteQuerySettings, BulkUpsertSettings, Ydb, };
7
9
  export function createExecuteQuerySettings(options) {
8
10
  const { keepInCache = true, idempotent = true } = options ?? {};
@@ -130,15 +132,100 @@ export function configureDriver(config) {
130
132
  }
131
133
  overrideConfig = config;
132
134
  }
135
+ function readStaticCredentialsPasswordFromFile(path) {
136
+ try {
137
+ return readFileSync(path, "utf8").replace(/[\r\n]+$/, "");
138
+ }
139
+ catch (cause) {
140
+ throw new Error(`Failed to read YDB_STATIC_CREDENTIALS_PASSWORD_FILE at ${path}.`, { cause });
141
+ }
142
+ }
143
+ function readSslRootCertificatesFromFile(path) {
144
+ try {
145
+ return readFileSync(path);
146
+ }
147
+ catch (cause) {
148
+ throw new Error(`Failed to read YDB_SSL_ROOT_CERTIFICATES_FILE at ${path}.`, { cause });
149
+ }
150
+ }
151
+ function resolveStaticCredentialsPassword() {
152
+ if (YDB_STATIC_CREDENTIALS_PASSWORD_FILE) {
153
+ const password = readStaticCredentialsPasswordFromFile(YDB_STATIC_CREDENTIALS_PASSWORD_FILE);
154
+ return password.length > 0 ? password : undefined;
155
+ }
156
+ return YDB_STATIC_CREDENTIALS_PASSWORD.length > 0
157
+ ? YDB_STATIC_CREDENTIALS_PASSWORD
158
+ : undefined;
159
+ }
160
+ function endpointFromConnectionString(connectionString) {
161
+ const url = new URL(connectionString);
162
+ return `${url.protocol}//${url.host}`;
163
+ }
164
+ function resolveStaticCredentialsAuthEndpoint(base) {
165
+ if (YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT) {
166
+ return YDB_STATIC_CREDENTIALS_AUTH_ENDPOINT;
167
+ }
168
+ if ("endpoint" in base) {
169
+ return base.endpoint;
170
+ }
171
+ return endpointFromConnectionString(base.connectionString);
172
+ }
173
+ function isSecureEndpoint(endpoint) {
174
+ return /^(grpcs|https):\/\//i.test(endpoint);
175
+ }
176
+ function createPrivateCaSslCredentialsForEndpoint(endpoint) {
177
+ if (!isSecureEndpoint(endpoint) || !YDB_SSL_ROOT_CERTIFICATES_FILE) {
178
+ return undefined;
179
+ }
180
+ return {
181
+ rootCertificates: readSslRootCertificatesFromFile(YDB_SSL_ROOT_CERTIFICATES_FILE),
182
+ };
183
+ }
184
+ function createSdkDefaultSslCredentialsForStaticAuth() {
185
+ try {
186
+ // ydb-sdk does not publicly export this helper; keep the private lookup lazy and non-fatal.
187
+ const { makeDefaultSslCredentials } = require(join(dirname(require.resolve("ydb-sdk")), "utils/ssl-credentials.js"));
188
+ return makeDefaultSslCredentials();
189
+ }
190
+ catch (cause) {
191
+ logger.warn({ err: cause }, "YDB SDK default SSL credentials unavailable; falling back to grpc default TLS roots");
192
+ return {};
193
+ }
194
+ }
195
+ function createStaticAuthSslCredentialsForEndpoint(endpoint) {
196
+ if (!isSecureEndpoint(endpoint)) {
197
+ return undefined;
198
+ }
199
+ return (createPrivateCaSslCredentialsForEndpoint(endpoint) ??
200
+ createSdkDefaultSslCredentialsForStaticAuth());
201
+ }
202
+ function createStaticCredentialsAuthService(base) {
203
+ if (!YDB_STATIC_CREDENTIALS_USER) {
204
+ return undefined;
205
+ }
206
+ const password = resolveStaticCredentialsPassword();
207
+ if (!password) {
208
+ throw new Error("YDB_STATIC_CREDENTIALS_USER is set, but neither YDB_STATIC_CREDENTIALS_PASSWORD_FILE nor YDB_STATIC_CREDENTIALS_PASSWORD provides a non-empty password.");
209
+ }
210
+ const authEndpoint = resolveStaticCredentialsAuthEndpoint(base);
211
+ const sslCredentials = createStaticAuthSslCredentialsForEndpoint(authEndpoint);
212
+ return new StaticCredentialsAuthService(YDB_STATIC_CREDENTIALS_USER, password, authEndpoint, getDefaultLogger(), sslCredentials ? { sslCredentials } : undefined);
213
+ }
133
214
  function getDriverConfig() {
134
215
  const base = resolveYdbConnectionConfig({
135
216
  endpoint: overrideConfig?.endpoint,
136
217
  database: overrideConfig?.database,
137
218
  connectionString: overrideConfig?.connectionString,
138
219
  });
220
+ const sslCredentials = "endpoint" in base
221
+ ? createPrivateCaSslCredentialsForEndpoint(base.endpoint)
222
+ : createPrivateCaSslCredentialsForEndpoint(endpointFromConnectionString(base.connectionString));
139
223
  return {
140
224
  ...base,
141
- authService: overrideConfig?.authService ?? getCredentialsFromEnv(),
225
+ authService: overrideConfig?.authService ??
226
+ createStaticCredentialsAuthService(base) ??
227
+ getCredentialsFromEnv(),
228
+ ...(sslCredentials ? { sslCredentials } : {}),
142
229
  poolSettings: {
143
230
  minLimit: SESSION_POOL_MIN_SIZE,
144
231
  maxLimit: SESSION_POOL_MAX_SIZE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ydb-qdrant",
3
- "version": "9.0.3",
3
+ "version": "9.1.1",
4
4
  "main": "dist/package/api.js",
5
5
  "types": "dist/package/api.d.ts",
6
6
  "exports": {