@bitofsky/databricks-sql 1.0.4 → 1.0.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/README.md +7 -1
- package/dist/index.cjs +42 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -3
- package/dist/index.d.ts +18 -3
- package/dist/index.js +42 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -209,6 +209,8 @@ function fetchRow(
|
|
|
209
209
|
```
|
|
210
210
|
- Streams each row to `options.onEachRow`.
|
|
211
211
|
- Use `format: 'JSON_OBJECT'` to map rows into schema-based objects.
|
|
212
|
+
- Use `encodeBigInt` to customize BIGINT/LONG conversions when using `JSON_OBJECT`.
|
|
213
|
+
- Use `encodeTimestamp` to customize TIMESTAMP* conversions when using `JSON_OBJECT`.
|
|
212
214
|
- Supports `INLINE` results or `JSON_ARRAY` formatted `EXTERNAL_LINKS` only.
|
|
213
215
|
- If only a subset of external links is returned, missing chunk metadata is fetched by index.
|
|
214
216
|
|
|
@@ -274,15 +276,19 @@ type ExecuteStatementOptions = {
|
|
|
274
276
|
|
|
275
277
|
type FetchRowsOptions = {
|
|
276
278
|
signal?: AbortSignal
|
|
277
|
-
onEachRow?: (row: RowArray | RowObject) => void
|
|
278
279
|
format?: 'JSON_ARRAY' | 'JSON_OBJECT'
|
|
279
280
|
logger?: Logger
|
|
281
|
+
onEachRow?: (row: RowArray | RowObject) => void
|
|
282
|
+
encodeBigInt?: (value: bigint) => unknown
|
|
283
|
+
encodeTimestamp?: (value: string) => unknown
|
|
280
284
|
}
|
|
281
285
|
|
|
282
286
|
type FetchAllOptions = {
|
|
283
287
|
signal?: AbortSignal
|
|
284
288
|
format?: 'JSON_ARRAY' | 'JSON_OBJECT'
|
|
285
289
|
logger?: Logger
|
|
290
|
+
encodeBigInt?: (value: bigint) => unknown
|
|
291
|
+
encodeTimestamp?: (value: string) => unknown
|
|
286
292
|
}
|
|
287
293
|
|
|
288
294
|
type FetchStreamOptions = {
|
package/dist/index.cjs
CHANGED
|
@@ -360,20 +360,18 @@ var INTEGER_TYPES = /* @__PURE__ */ new Set(["TINYINT", "SMALLINT", "INT"]);
|
|
|
360
360
|
var BIGINT_TYPES = /* @__PURE__ */ new Set(["BIGINT", "LONG"]);
|
|
361
361
|
var FLOAT_TYPES = /* @__PURE__ */ new Set(["FLOAT", "DOUBLE"]);
|
|
362
362
|
var BOOLEAN_TYPES = /* @__PURE__ */ new Set(["BOOLEAN"]);
|
|
363
|
+
var TIMESTAMP_TYPES = /* @__PURE__ */ new Set(["TIMESTAMP", "TIMESTAMP_NTZ", "TIMESTAMP_LTZ"]);
|
|
363
364
|
var STRING_TYPES = /* @__PURE__ */ new Set([
|
|
364
365
|
"STRING",
|
|
365
366
|
"DATE",
|
|
366
|
-
"TIMESTAMP",
|
|
367
|
-
"TIMESTAMP_NTZ",
|
|
368
|
-
"TIMESTAMP_LTZ",
|
|
369
367
|
"TIME"
|
|
370
368
|
]);
|
|
371
|
-
function createRowMapper(manifest, format) {
|
|
369
|
+
function createRowMapper(manifest, format, options = {}) {
|
|
372
370
|
if (format !== "JSON_OBJECT")
|
|
373
371
|
return (row) => row;
|
|
374
372
|
const columnConverters = manifest.schema.columns.map((column) => ({
|
|
375
373
|
name: column.name,
|
|
376
|
-
convert: createColumnConverter(column)
|
|
374
|
+
convert: createColumnConverter(column, options)
|
|
377
375
|
}));
|
|
378
376
|
return (row) => {
|
|
379
377
|
const mapped = {};
|
|
@@ -388,9 +386,9 @@ function createRowMapper(manifest, format) {
|
|
|
388
386
|
return mapped;
|
|
389
387
|
};
|
|
390
388
|
}
|
|
391
|
-
function createColumnConverter(column) {
|
|
389
|
+
function createColumnConverter(column, options) {
|
|
392
390
|
const descriptor = parseColumnType(column);
|
|
393
|
-
return (value) => convertValue(descriptor, value);
|
|
391
|
+
return (value) => convertValue(descriptor, value, options);
|
|
394
392
|
}
|
|
395
393
|
function parseColumnType(column) {
|
|
396
394
|
if (column.type_name === "STRUCT" || column.type_name === "ARRAY" || column.type_name === "MAP")
|
|
@@ -531,45 +529,47 @@ function stripNotNull(typeText) {
|
|
|
531
529
|
trimmed = trimmed.slice(0, -"NOT NULL".length).trim();
|
|
532
530
|
return trimmed;
|
|
533
531
|
}
|
|
534
|
-
function convertValue(descriptor, value) {
|
|
532
|
+
function convertValue(descriptor, value, options) {
|
|
535
533
|
if (value === null || value === void 0)
|
|
536
534
|
return value;
|
|
537
535
|
if (descriptor.typeName === "STRUCT" && descriptor.fields)
|
|
538
|
-
return convertStructValue(descriptor.fields, value);
|
|
536
|
+
return convertStructValue(descriptor.fields, value, options);
|
|
539
537
|
if (descriptor.typeName === "ARRAY" && descriptor.elementType)
|
|
540
|
-
return convertArrayValue(descriptor.elementType, value);
|
|
538
|
+
return convertArrayValue(descriptor.elementType, value, options);
|
|
541
539
|
if (descriptor.typeName === "MAP" && descriptor.keyType && descriptor.valueType)
|
|
542
|
-
return convertMapValue(descriptor.keyType, descriptor.valueType, value);
|
|
540
|
+
return convertMapValue(descriptor.keyType, descriptor.valueType, value, options);
|
|
543
541
|
if (descriptor.typeName === "DECIMAL")
|
|
544
542
|
return convertNumber(value);
|
|
545
543
|
if (INTEGER_TYPES.has(descriptor.typeName))
|
|
546
544
|
return convertNumber(value);
|
|
547
545
|
if (BIGINT_TYPES.has(descriptor.typeName))
|
|
548
|
-
return convertInteger(value);
|
|
546
|
+
return convertInteger(value, options.encodeBigInt);
|
|
549
547
|
if (FLOAT_TYPES.has(descriptor.typeName))
|
|
550
548
|
return convertNumber(value);
|
|
551
549
|
if (BOOLEAN_TYPES.has(descriptor.typeName))
|
|
552
550
|
return convertBoolean(value);
|
|
551
|
+
if (TIMESTAMP_TYPES.has(descriptor.typeName))
|
|
552
|
+
return convertTimestamp(value, options.encodeTimestamp);
|
|
553
553
|
if (STRING_TYPES.has(descriptor.typeName))
|
|
554
554
|
return value;
|
|
555
555
|
return value;
|
|
556
556
|
}
|
|
557
|
-
function convertStructValue(fields, value) {
|
|
557
|
+
function convertStructValue(fields, value, options) {
|
|
558
558
|
const raw = parseStructValue(value);
|
|
559
559
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
560
560
|
return value;
|
|
561
561
|
const mapped = {};
|
|
562
562
|
for (const field of fields)
|
|
563
|
-
mapped[field.name] = convertValue(field.type, raw[field.name]);
|
|
563
|
+
mapped[field.name] = convertValue(field.type, raw[field.name], options);
|
|
564
564
|
return mapped;
|
|
565
565
|
}
|
|
566
|
-
function convertArrayValue(elementType, value) {
|
|
566
|
+
function convertArrayValue(elementType, value, options) {
|
|
567
567
|
const raw = parseJsonValue(value);
|
|
568
568
|
if (!Array.isArray(raw))
|
|
569
569
|
return value;
|
|
570
|
-
return raw.map((entry) => convertValue(elementType, entry));
|
|
570
|
+
return raw.map((entry) => convertValue(elementType, entry, options));
|
|
571
571
|
}
|
|
572
|
-
function convertMapValue(keyType, valueType, value) {
|
|
572
|
+
function convertMapValue(keyType, valueType, value, options) {
|
|
573
573
|
const raw = parseJsonValue(value);
|
|
574
574
|
if (!raw || typeof raw !== "object")
|
|
575
575
|
return value;
|
|
@@ -578,15 +578,15 @@ function convertMapValue(keyType, valueType, value) {
|
|
|
578
578
|
for (const entry of raw) {
|
|
579
579
|
if (!Array.isArray(entry) || entry.length < 2)
|
|
580
580
|
continue;
|
|
581
|
-
const convertedKey = convertValue(keyType, entry[0]);
|
|
582
|
-
mapped2[String(convertedKey)] = convertValue(valueType, entry[1]);
|
|
581
|
+
const convertedKey = convertValue(keyType, entry[0], options);
|
|
582
|
+
mapped2[String(convertedKey)] = convertValue(valueType, entry[1], options);
|
|
583
583
|
}
|
|
584
584
|
return mapped2;
|
|
585
585
|
}
|
|
586
586
|
const mapped = {};
|
|
587
587
|
for (const [key, entryValue] of Object.entries(raw)) {
|
|
588
|
-
const convertedKey = convertValue(keyType, key);
|
|
589
|
-
mapped[String(convertedKey)] = convertValue(valueType, entryValue);
|
|
588
|
+
const convertedKey = convertValue(keyType, key, options);
|
|
589
|
+
mapped[String(convertedKey)] = convertValue(valueType, entryValue, options);
|
|
590
590
|
}
|
|
591
591
|
return mapped;
|
|
592
592
|
}
|
|
@@ -615,23 +615,31 @@ function convertNumber(value) {
|
|
|
615
615
|
}
|
|
616
616
|
return value;
|
|
617
617
|
}
|
|
618
|
-
function convertInteger(value) {
|
|
618
|
+
function convertInteger(value, encodeBigInt) {
|
|
619
619
|
if (typeof value === "bigint")
|
|
620
|
-
return value;
|
|
620
|
+
return encodeBigInt ? encodeBigInt(value) : value;
|
|
621
621
|
if (typeof value === "number") {
|
|
622
|
-
if (Number.isInteger(value))
|
|
623
|
-
|
|
622
|
+
if (Number.isInteger(value)) {
|
|
623
|
+
const bigintValue = BigInt(value);
|
|
624
|
+
return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue;
|
|
625
|
+
}
|
|
624
626
|
return value;
|
|
625
627
|
}
|
|
626
628
|
if (typeof value === "string") {
|
|
627
629
|
try {
|
|
628
|
-
|
|
630
|
+
const bigintValue = BigInt(value);
|
|
631
|
+
return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue;
|
|
629
632
|
} catch {
|
|
630
633
|
return value;
|
|
631
634
|
}
|
|
632
635
|
}
|
|
633
636
|
return value;
|
|
634
637
|
}
|
|
638
|
+
function convertTimestamp(value, encodeTimestamp) {
|
|
639
|
+
if (typeof value !== "string")
|
|
640
|
+
return value;
|
|
641
|
+
return encodeTimestamp ? encodeTimestamp(value) : value;
|
|
642
|
+
}
|
|
635
643
|
function convertBoolean(value) {
|
|
636
644
|
if (typeof value === "boolean")
|
|
637
645
|
return value;
|
|
@@ -761,7 +769,10 @@ async function fetchRow(statementResult, auth, options = {}) {
|
|
|
761
769
|
const manifest = validateSucceededResult(statementResult);
|
|
762
770
|
const statementId = statementResult.statement_id;
|
|
763
771
|
const logContext = { statementId, manifest, requestedFormat: format };
|
|
764
|
-
const mapRow = createRowMapper(manifest, format
|
|
772
|
+
const mapRow = createRowMapper(manifest, format, {
|
|
773
|
+
...options.encodeBigInt ? { encodeBigInt: options.encodeBigInt } : {},
|
|
774
|
+
...options.encodeTimestamp ? { encodeTimestamp: options.encodeTimestamp } : {}
|
|
775
|
+
});
|
|
765
776
|
logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {
|
|
766
777
|
...logContext,
|
|
767
778
|
resultType: statementResult.result?.external_links ? "EXTERNAL_LINKS" : "INLINE"
|
|
@@ -857,6 +868,10 @@ async function fetchAll(statementResult, auth, options = {}) {
|
|
|
857
868
|
fetchOptions.format = options.format;
|
|
858
869
|
if (options.logger)
|
|
859
870
|
fetchOptions.logger = options.logger;
|
|
871
|
+
if (options.encodeBigInt)
|
|
872
|
+
fetchOptions.encodeBigInt = options.encodeBigInt;
|
|
873
|
+
if (options.encodeTimestamp)
|
|
874
|
+
fetchOptions.encodeTimestamp = options.encodeTimestamp;
|
|
860
875
|
await fetchRow(statementResult, auth, fetchOptions);
|
|
861
876
|
logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {
|
|
862
877
|
...logContext,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/util.ts","../src/http.ts","../src/databricks-api.ts","../src/api/executeStatement.ts","../src/api/fetchRow.ts","../src/createRowMapper.ts","../src/api/fetchStream.ts","../src/api/fetchAll.ts","../src/api/mergeExternalLinks.ts"],"sourcesContent":["// Types\nexport type * from './types.js'\n\n// Errors\nexport * from './errors.js'\n\n// Core functions\nexport * from './api/index.js'\n","/** Base error for Databricks SQL operations */\nexport class DatabricksSqlError extends Error {\n readonly code: string\n readonly statementId: string | undefined\n\n constructor(message: string, code?: string, statementId?: string) {\n super(message)\n this.name = 'DatabricksSqlError'\n this.code = code ?? 'UNKNOWN_ERROR'\n this.statementId = statementId\n Error.captureStackTrace?.(this, DatabricksSqlError)\n }\n}\n\n/** Error when statement is cancelled */\nexport class StatementCancelledError extends DatabricksSqlError {\n constructor(statementId: string) {\n super(`Statement ${statementId} was cancelled`, 'CANCELLED', statementId)\n this.name = 'StatementCancelledError'\n }\n}\n\n/** Error when operation is aborted via AbortSignal */\nexport class AbortError extends DatabricksSqlError {\n constructor(message: string = 'Operation was aborted') {\n super(message, 'ABORTED')\n this.name = 'AbortError'\n }\n}\n\n/** HTTP error from API calls */\nexport class HttpError extends DatabricksSqlError {\n readonly status: number\n readonly statusText: string\n\n constructor(status: number, statusText: string, message?: string) {\n super(message ?? `HTTP ${status}: ${statusText}`, `HTTP_${status}`)\n this.name = 'HttpError'\n this.status = status\n this.statusText = statusText\n }\n}\n\n/** Authentication error (401) */\nexport class AuthenticationError extends HttpError {\n constructor() {\n super(401, 'Unauthorized', 'Authentication failed. Check your token.')\n this.name = 'AuthenticationError'\n }\n}\n\n/** Rate limit error (429) */\nexport class RateLimitError extends HttpError {\n readonly retryAfter: number | undefined\n\n constructor(retryAfter?: number) {\n super(429, 'Too Many Requests', 'Rate limit exceeded')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n","import { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as WebReadableStream } from 'node:stream/web'\nimport type { StatementResult, StatementManifest } from './types.js'\nimport { AbortError, DatabricksSqlError } from './errors.js'\n\n/**\n * Extract warehouse_id from httpPath\n * @example \"/sql/1.0/warehouses/abc123def456\" -> \"abc123def456\"\n */\nexport function extractWarehouseId(httpPath: string): string {\n const match = httpPath.match(/\\/sql\\/\\d+\\.\\d+\\/warehouses\\/([a-zA-Z0-9]+)/)\n if (!match?.[1])\n throw new Error(`Cannot extract warehouse_id from httpPath: ${httpPath}`)\n return match[1]\n}\n\n/**\n * Throw AbortError if signal is aborted\n */\nexport function throwIfAborted(signal: AbortSignal | undefined, context: string): void {\n if (signal?.aborted)\n throw new AbortError(`[${context}] Aborted`)\n}\n\n/**\n * Delay for specified milliseconds with AbortSignal support\n */\nexport async function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted)\n return reject(new AbortError('Aborted before delay'))\n\n let settled = false\n\n const onAbort = () => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n reject(new AbortError('Aborted during delay'))\n }\n\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * Build full URL from host and path\n */\nexport function buildUrl(host: string, path: string): string {\n const base = host.startsWith('https://') ? host : `https://${host}`\n return new URL(path, base).href\n}\n\n/**\n * Validate statement result is in SUCCEEDED state with manifest.\n * Returns the manifest for convenience.\n * @throws {DatabricksSqlError} If state is not SUCCEEDED or manifest is missing\n */\nexport function validateSucceededResult(\n statementResult: StatementResult\n): StatementManifest {\n if (statementResult.status.state !== 'SUCCEEDED')\n throw new DatabricksSqlError(\n `Cannot fetch from non-succeeded statement: ${statementResult.status.state}`,\n 'INVALID_STATE',\n statementResult.statement_id\n )\n\n if (!statementResult.manifest)\n throw new DatabricksSqlError(\n 'Statement result has no manifest',\n 'MISSING_MANIFEST',\n statementResult.statement_id\n )\n\n return statementResult.manifest\n}\n\nfunction isWebReadableStream(body: unknown): body is WebReadableStream {\n return typeof (body as WebReadableStream).getReader === 'function'\n}\n\nexport async function pipeUrlToOutput(\n url: string,\n output: NodeJS.WritableStream,\n signal?: AbortSignal\n): Promise<void> {\n // Uses Node 20+ global fetch with Web streams.\n if (signal?.aborted)\n throw new AbortError('Aborted while streaming')\n\n const response = await fetch(url, signal ? { signal } : undefined)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch external link: ${response.status} ${response.statusText}`\n )\n }\n\n if (!response.body)\n return void output.end()\n\n const body = response.body\n const input = isWebReadableStream(body)\n ? Readable.fromWeb(body)\n : (body as NodeJS.ReadableStream)\n\n await pipeline(input, output)\n}\n","import type { AuthInfo } from './types.js'\nimport {\n HttpError,\n AuthenticationError,\n RateLimitError,\n AbortError,\n} from './errors.js'\nimport { buildUrl, delay } from './util.js'\n\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY_MS = 1000\n\ntype HttpMethod = 'GET' | 'POST' | 'DELETE'\n\ntype HttpRequestOptions = {\n method: HttpMethod\n path: string\n body?: unknown\n signal?: AbortSignal\n}\n\n/**\n * HTTP request wrapper with retry and error handling\n */\nexport async function httpRequest<T>(\n auth: AuthInfo,\n options: HttpRequestOptions\n): Promise<T> {\n const { method, path, body, signal } = options\n const url = buildUrl(auth.host, path)\n\n let lastError: Error | undefined\n let retryDelay = INITIAL_RETRY_DELAY_MS\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n if (signal?.aborted)\n throw new AbortError()\n\n try {\n // Build a minimal fetch init, skipping undefined values.\n const fetchInit = Object.fromEntries(\n Object.entries({\n method,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n }).filter(([, v]) => v !== undefined)\n ) as RequestInit\n\n const response = await fetch(url, fetchInit)\n\n // Success\n if (response.ok)\n return (await response.json()) as T\n\n // Authentication error (no retry)\n if (response.status === 401)\n throw new AuthenticationError()\n\n // Rate limit\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get('Retry-After')\n const retryAfter = retryAfterHeader\n ? parseInt(retryAfterHeader, 10)\n : undefined\n const error = new RateLimitError(\n isNaN(retryAfter as number) ? undefined : retryAfter\n )\n\n if (error.retryAfter && attempt < MAX_RETRIES) {\n await delay(error.retryAfter * 1000, signal)\n continue\n }\n\n throw error\n }\n\n // Server error (can retry)\n if (response.status >= 500) {\n const errorBody = await response.text().catch(() => '')\n lastError = new HttpError(response.status, response.statusText, errorBody)\n\n if (attempt < MAX_RETRIES) {\n // Exponential backoff for transient server errors.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n // Other client errors\n const errorBody = await response.text().catch(() => '')\n\n throw new HttpError(response.status, response.statusText, errorBody)\n\n } catch (err) {\n // Re-throw known errors\n if (\n err instanceof AbortError ||\n err instanceof AuthenticationError ||\n err instanceof HttpError\n )\n throw err\n\n // Network error\n if (err instanceof TypeError && err.message.includes('fetch')) {\n lastError = err\n if (attempt < MAX_RETRIES) {\n // Network errors are retried with backoff.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n throw err\n }\n }\n\n throw lastError ?? new Error('Request failed after retries')\n}\n","import type {\n AuthInfo,\n ExecuteStatementRequest,\n StatementResult,\n GetChunkResponse,\n QueryInfo,\n} from './types.js'\nimport { httpRequest } from './http.js'\n\n// Base path for Databricks SQL Statement Execution API.\nconst BASE_PATH = '/api/2.0/sql/statements'\n// Base path for Query History API.\nconst HISTORY_BASE_PATH = '/api/2.0/sql/history/queries'\n\n/**\n * Execute SQL statement\n * POST /api/2.0/sql/statements\n */\nexport async function postStatement(\n auth: AuthInfo,\n request: ExecuteStatementRequest,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'POST',\n path: BASE_PATH,\n body: request,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get statement status and result\n * GET /api/2.0/sql/statements/{statement_id}\n */\nexport async function getStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Cancel statement execution\n * POST /api/2.0/sql/statements/{statement_id}/cancel\n */\nexport async function cancelStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<void> {\n await httpRequest<unknown>(auth, {\n method: 'POST',\n path: `${BASE_PATH}/${statementId}/cancel`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get result chunk by index\n * GET /api/2.0/sql/statements/{statement_id}/result/chunks/{chunk_index}\n */\nexport async function getChunk(\n auth: AuthInfo,\n statementId: string,\n chunkIndex: number,\n signal?: AbortSignal\n): Promise<GetChunkResponse> {\n return httpRequest<GetChunkResponse>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}/result/chunks/${chunkIndex}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get query metrics from Query History API\n * GET /api/2.0/sql/history/queries/{query_id}?include_metrics=true\n */\nexport async function getQueryMetrics(\n auth: AuthInfo,\n queryId: string,\n signal?: AbortSignal\n): Promise<QueryInfo> {\n return httpRequest<QueryInfo>(auth, {\n method: 'GET',\n path: `${HISTORY_BASE_PATH}/${queryId}?include_metrics=true`,\n ...(signal ? { signal } : {}),\n })\n}\n","import type {\n AuthInfo,\n ExecuteStatementOptions,\n ExecuteStatementRequest,\n StatementResult,\n StatementState,\n QueryMetrics,\n} from '../types.js'\nimport { postStatement, getStatement, cancelStatement, getQueryMetrics } from '../databricks-api.js'\nimport { extractWarehouseId, throwIfAborted, delay } from '../util.js'\nimport {\n DatabricksSqlError,\n StatementCancelledError,\n AbortError,\n} from '../errors.js'\n\nconst TERMINAL_STATES = new Set<StatementState>([\n 'SUCCEEDED',\n 'FAILED',\n 'CANCELED',\n 'CLOSED',\n])\nconst POLL_INTERVAL_MS = 5000\n\nasync function fetchMetrics(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<QueryMetrics | undefined> {\n const queryInfo = await getQueryMetrics(auth, statementId, signal)\n return queryInfo.metrics\n}\n\n/**\n * Execute SQL statement and poll until completion\n */\nexport async function executeStatement(\n query: string,\n auth: AuthInfo,\n options: ExecuteStatementOptions = {}\n): Promise<StatementResult> {\n const warehouseId = options.warehouse_id ?? extractWarehouseId(auth.httpPath)\n const { signal, onProgress, enableMetrics, logger } = options\n const waitTimeout = options.wait_timeout ?? (onProgress ? '0s' : '50s')\n let cancelIssued = false\n\n // Check if already aborted\n throwIfAborted(signal, 'executeStatement')\n\n // Helper to call onProgress with optional metrics\n const emitProgress = onProgress\n ? async () => result ? onProgress(\n result,\n enableMetrics ? await fetchMetrics(auth, result.statement_id, signal).catch(e => {\n logger?.error?.(`executeStatement Failed to fetch query metrics for statement ${result?.statement_id}: ${String(e)}`, { statementId: result?.statement_id })\n return undefined\n }) : undefined\n ) : undefined\n : undefined\n\n // 1. Build request (filter out undefined values)\n const request = Object.fromEntries(\n Object.entries({\n warehouse_id: warehouseId,\n statement: query,\n byte_limit: options.byte_limit,\n disposition: options.disposition,\n format: options.format,\n on_wait_timeout: options.on_wait_timeout ?? 'CONTINUE',\n wait_timeout: waitTimeout,\n row_limit: options.row_limit,\n catalog: options.catalog,\n schema: options.schema,\n parameters: options.parameters,\n }).filter(([, v]) => v !== undefined)\n ) as ExecuteStatementRequest\n\n logger?.info?.(`executeStatement Executing statement on warehouse ${warehouseId}...`)\n\n // 2. Submit statement execution request\n let result = await postStatement(auth, request, signal)\n const cancelStatementSafely = async () => {\n if (cancelIssued) return\n logger?.info?.('executeStatement Abort signal received during executeStatement.')\n cancelIssued = true\n await cancelStatement(auth, result.statement_id).catch((err) => {\n logger?.error?.('executeStatement Failed to cancel statement after abort.', err)\n })\n }\n\n if (signal?.aborted) {\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n\n const onAbort = () => cancelStatementSafely().catch(() => { })\n\n try {\n signal?.addEventListener('abort', onAbort, { once: true })\n\n // 3. Poll until terminal state\n while (!TERMINAL_STATES.has(result.status.state)) {\n logger?.info?.(`executeStatement Statement ${result.statement_id} in state ${result.status.state}; polling for status...`)\n await delay(POLL_INTERVAL_MS, signal)\n result = await getStatement(auth, result.statement_id, signal)\n await emitProgress?.()\n }\n } catch (err) {\n if (err instanceof AbortError || signal?.aborted) {\n logger?.info?.('executeStatement Abort detected in executeStatement polling loop.')\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n logger?.error?.(`executeStatement Error during executeStatement polling: ${String(err)}`)\n throw err\n } finally {\n logger?.info?.(`executeStatement Statement ${result.statement_id} reached final state: ${result.status.state}`)\n signal?.removeEventListener('abort', onAbort)\n }\n\n // 4. Final progress callback\n await emitProgress?.()\n\n // 5. Handle terminal states\n if (result.status.state === 'SUCCEEDED')\n return result\n\n if (result.status.state === 'CANCELED')\n throw new StatementCancelledError(result.statement_id)\n\n // FAILED or CLOSED\n throw new DatabricksSqlError(\n result.status.error?.message ?? 'Statement execution failed',\n result.status.error?.error_code,\n result.statement_id\n )\n}\n","import type { Readable } from 'node:stream'\nimport type {\n AuthInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { parser } from 'stream-json'\nimport { streamArray } from 'stream-json/streamers/StreamArray'\n\nimport { getChunk } from '../databricks-api.js'\nimport { createRowMapper } from '../createRowMapper.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Process each row from statement result with a callback.\n * Supports INLINE results and JSON_ARRAY external links.\n */\nexport async function fetchRow(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchRowsOptions = {}\n): Promise<void> {\n const { signal, onEachRow, format, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const statementId = statementResult.statement_id\n const logContext = { statementId, manifest, requestedFormat: format }\n // Map JSON_ARRAY rows to JSON_OBJECT when requested.\n const mapRow = createRowMapper(manifest, format)\n\n logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {\n ...logContext,\n resultType: statementResult.result?.external_links ? 'EXTERNAL_LINKS' : 'INLINE',\n })\n\n if (statementResult.result?.external_links) {\n if (manifest.format !== 'JSON_ARRAY') {\n logger?.error?.(`fetchRow only supports JSON_ARRAY for external_links; got ${manifest.format}.`, logContext)\n throw new DatabricksSqlError(\n `fetchRow only supports JSON_ARRAY for external_links. Received: ${manifest.format}`,\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchRow streaming external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...logger ? { logger } : {},\n })\n await consumeJsonArrayStream(stream, mapRow, onEachRow, signal, logger, logContext)\n return\n }\n\n const totalChunks = manifest.total_chunk_count\n\n // Process first chunk (inline data_array)\n const dataArray = statementResult.result?.data_array\n if (dataArray) {\n logger?.info?.(`fetchRow processing inline rows for statement ${statementId}.`, {\n ...logContext,\n inlineRows: dataArray.length,\n })\n for (const row of dataArray) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Convert row to requested shape before callback.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n\n // Process additional chunks if any\n if (totalChunks > 1) {\n logger?.info?.(`fetchRow processing ${totalChunks} chunks for statement ${statementId}.`, logContext)\n for (let chunkIndex = 1; chunkIndex < totalChunks; chunkIndex++) {\n if (signal?.aborted) throw new AbortError('Aborted')\n\n const chunk = await getChunk(auth, statementId, chunkIndex, signal)\n\n // Additional chunks should also be data_array (INLINE)\n if (chunk.external_links)\n throw new DatabricksSqlError(\n 'fetchRow only supports INLINE results. Chunk contains external_links.',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n\n if (chunk.data_array) {\n for (const row of chunk.data_array) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Apply the same mapping for each chunked row.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n }\n }\n}\n\nasync function consumeJsonArrayStream(\n stream: Readable,\n mapRow: (row: RowArray) => RowArray | RowObject,\n onEachRow: ((row: RowArray | RowObject) => void) | undefined,\n signal: AbortSignal | undefined,\n logger: FetchRowsOptions['logger'],\n logContext: Record<string, unknown>\n): Promise<void> {\n // Stream JSON_ARRAY as individual rows to avoid buffering whole payloads.\n const jsonStream = stream.pipe(parser()).pipe(streamArray())\n\n for await (const item of jsonStream) {\n if (signal?.aborted) {\n logger?.info?.('fetchRow abort detected while streaming JSON_ARRAY rows.', {\n ...logContext,\n aborted: signal.aborted,\n })\n stream.destroy(new AbortError('Aborted'))\n throw new AbortError('Aborted')\n }\n\n const row = item.value\n if (!Array.isArray(row)) {\n throw new DatabricksSqlError(\n 'Expected JSON_ARRAY rows to be arrays',\n 'INVALID_FORMAT'\n )\n }\n\n onEachRow?.(mapRow(row))\n }\n}\n","import { DatabricksSqlError } from './errors.js'\nimport type {\n ColumnInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementManifest,\n} from './types.js'\n\ntype RowMapper = (row: RowArray) => RowArray | RowObject\n\ntype TypeDescriptor = {\n typeName: string\n typeText: string\n precision?: number\n scale?: number\n fields?: StructField[]\n elementType?: TypeDescriptor\n keyType?: TypeDescriptor\n valueType?: TypeDescriptor\n}\n\ntype StructField = {\n name: string\n type: TypeDescriptor\n}\n\n// Type buckets used for value conversion decisions.\nconst INTEGER_TYPES = new Set(['TINYINT', 'SMALLINT', 'INT'])\nconst BIGINT_TYPES = new Set(['BIGINT', 'LONG'])\nconst FLOAT_TYPES = new Set(['FLOAT', 'DOUBLE'])\nconst BOOLEAN_TYPES = new Set(['BOOLEAN'])\nconst STRING_TYPES = new Set([\n 'STRING',\n 'DATE',\n 'TIMESTAMP',\n 'TIMESTAMP_NTZ',\n 'TIMESTAMP_LTZ',\n 'TIME',\n])\n\n/**\n * Create a row mapper that converts JSON_ARRAY rows into JSON_OBJECTs.\n * Datetime-like fields are preserved as strings to avoid locale/zone surprises.\n * DECIMAL values are converted to numbers to match the Databricks SDK behavior.\n */\nexport function createRowMapper(\n manifest: StatementManifest,\n format: FetchRowsOptions['format']\n): RowMapper {\n if (format !== 'JSON_OBJECT')\n return (row) => row\n\n // Precompute per-column converters for fast row mapping.\n const columnConverters = manifest.schema.columns.map((column: ColumnInfo) => ({\n name: column.name,\n convert: createColumnConverter(column),\n }))\n\n return (row) => {\n const mapped: RowObject = {}\n for (let index = 0; index < columnConverters.length; index++) {\n const converter = columnConverters[index]\n if (!converter)\n continue\n\n const { name, convert } = converter\n if (name)\n mapped[name] = convert(row[index])\n }\n return mapped\n }\n}\n\nfunction createColumnConverter(column: ColumnInfo): (value: unknown) => unknown {\n const descriptor = parseColumnType(column)\n return (value) => convertValue(descriptor, value)\n}\n\nfunction parseColumnType(column: ColumnInfo): TypeDescriptor {\n if (column.type_name === 'STRUCT' || column.type_name === 'ARRAY' || column.type_name === 'MAP')\n return parseTypeDescriptor(column.type_text)\n\n if (column.type_name === 'DECIMAL')\n // Prefer precision/scale provided by the API when available.\n return createDecimalDescriptor({\n typeName: column.type_name,\n typeText: column.type_text,\n }, column.type_precision, column.type_scale)\n\n return {\n typeName: column.type_name,\n typeText: column.type_text,\n }\n}\n\nfunction parseTypeDescriptor(typeText: string): TypeDescriptor {\n const trimmed = typeText.trim()\n const typeName = getTypeName(trimmed)\n\n if (typeName === 'STRUCT')\n // STRUCT fields are parsed recursively from type_text.\n return {\n typeName,\n typeText: trimmed,\n fields: parseStructFields(trimmed),\n }\n\n if (typeName === 'ARRAY') {\n const elementTypeText = parseSingleTypeArgument(trimmed)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (elementTypeText)\n descriptor.elementType = parseTypeDescriptor(elementTypeText)\n return descriptor\n }\n\n if (typeName === 'MAP') {\n const [keyTypeText, valueTypeText] = parseTypeArguments(trimmed, 2)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (keyTypeText)\n descriptor.keyType = parseTypeDescriptor(keyTypeText)\n if (valueTypeText)\n descriptor.valueType = parseTypeDescriptor(valueTypeText)\n return descriptor\n }\n\n if (typeName === 'DECIMAL') {\n // DECIMAL(precision, scale) needs explicit parsing for integer conversion.\n const { precision, scale } = parseDecimalInfo(trimmed)\n return createDecimalDescriptor({ typeName, typeText: trimmed }, precision, scale)\n }\n\n return {\n typeName,\n typeText: trimmed,\n }\n}\n\nfunction getTypeName(typeText: string): string {\n return typeText.match(/^[A-Z_]+/)?.[0] ?? typeText\n}\n\nfunction parseDecimalInfo(typeText: string): { precision?: number; scale?: number } {\n const match = typeText.match(/DECIMAL\\((\\d+),\\s*(\\d+)\\)/)\n if (!match)\n return {}\n\n return {\n precision: Number(match[1]),\n scale: Number(match[2]),\n }\n}\n\nfunction createDecimalDescriptor(\n base: Omit<TypeDescriptor, 'precision' | 'scale'>,\n precision?: number,\n scale?: number\n): TypeDescriptor {\n const descriptor: TypeDescriptor = { ...base }\n if (precision !== undefined)\n descriptor.precision = precision\n if (scale !== undefined)\n descriptor.scale = scale\n return descriptor\n}\n\nfunction parseStructFields(typeText: string): StructField[] {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n // Split by commas only at the top level of nested type definitions.\n const parts = splitTopLevel(inner)\n const fields: StructField[] = []\n\n for (const part of parts) {\n const separatorIndex = part.indexOf(':')\n if (separatorIndex === -1)\n continue\n\n const name = part.slice(0, separatorIndex).trim()\n let fieldTypeText = part.slice(separatorIndex + 1).trim()\n fieldTypeText = stripNotNull(fieldTypeText)\n\n if (!name)\n continue\n\n fields.push({\n name,\n type: parseTypeDescriptor(fieldTypeText),\n })\n }\n\n return fields\n}\n\nfunction parseSingleTypeArgument(typeText: string): string | null {\n const [arg] = parseTypeArguments(typeText, 1)\n return arg ?? null\n}\n\nfunction parseTypeArguments(typeText: string, expectedCount: number): Array<string | undefined> {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n const parts = splitTopLevel(inner)\n if (parts.length < expectedCount)\n return parts\n\n return parts.slice(0, expectedCount).map((part) => stripNotNull(part.trim()))\n}\n\nfunction splitTopLevel(value: string): string[] {\n const result: string[] = []\n let current = ''\n let angleDepth = 0\n let parenDepth = 0\n\n for (const char of value) {\n if (char === '<') angleDepth++\n if (char === '>') angleDepth--\n if (char === '(') parenDepth++\n if (char === ')') parenDepth--\n\n if (char === ',' && angleDepth === 0 && parenDepth === 0) {\n result.push(current.trim())\n current = ''\n continue\n }\n\n current += char\n }\n\n if (current.trim().length > 0)\n result.push(current.trim())\n\n return result\n}\n\nfunction stripNotNull(typeText: string): string {\n let trimmed = typeText.trim()\n while (trimmed.endsWith('NOT NULL'))\n trimmed = trimmed.slice(0, -'NOT NULL'.length).trim()\n return trimmed\n}\n\nfunction convertValue(descriptor: TypeDescriptor, value: unknown): unknown {\n if (value === null || value === undefined)\n return value\n\n if (descriptor.typeName === 'STRUCT' && descriptor.fields)\n // STRUCT values are JSON strings in JSON_ARRAY format.\n return convertStructValue(descriptor.fields, value)\n\n if (descriptor.typeName === 'ARRAY' && descriptor.elementType)\n return convertArrayValue(descriptor.elementType, value)\n\n if (descriptor.typeName === 'MAP' && descriptor.keyType && descriptor.valueType)\n return convertMapValue(descriptor.keyType, descriptor.valueType, value)\n\n if (descriptor.typeName === 'DECIMAL')\n return convertNumber(value)\n\n if (INTEGER_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BIGINT_TYPES.has(descriptor.typeName))\n return convertInteger(value)\n\n if (FLOAT_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BOOLEAN_TYPES.has(descriptor.typeName))\n return convertBoolean(value)\n\n if (STRING_TYPES.has(descriptor.typeName))\n return value\n\n return value\n}\n\nfunction convertStructValue(fields: StructField[], value: unknown): unknown {\n const raw = parseStructValue(value)\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return value\n\n // Apply nested field conversions based on the parsed STRUCT schema.\n const mapped: RowObject = {}\n for (const field of fields)\n mapped[field.name] = convertValue(field.type, (raw as RowObject)[field.name])\n\n return mapped\n}\n\nfunction convertArrayValue(elementType: TypeDescriptor, value: unknown): unknown {\n const raw = parseJsonValue(value)\n if (!Array.isArray(raw))\n return value\n\n return raw.map((entry) => convertValue(elementType, entry))\n}\n\nfunction convertMapValue(\n keyType: TypeDescriptor,\n valueType: TypeDescriptor,\n value: unknown\n): unknown {\n const raw = parseJsonValue(value)\n if (!raw || typeof raw !== 'object')\n return value\n\n if (Array.isArray(raw)) {\n const mapped: RowObject = {}\n for (const entry of raw) {\n if (!Array.isArray(entry) || entry.length < 2)\n continue\n const convertedKey = convertValue(keyType, entry[0])\n mapped[String(convertedKey)] = convertValue(valueType, entry[1])\n }\n return mapped\n }\n\n const mapped: RowObject = {}\n for (const [key, entryValue] of Object.entries(raw)) {\n const convertedKey = convertValue(keyType, key)\n mapped[String(convertedKey)] = convertValue(valueType, entryValue)\n }\n\n return mapped\n}\n\nfunction parseStructValue(value: unknown): RowObject | null {\n const parsed = parseJsonValue(value)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed as RowObject\n\n return parsed as RowObject | null\n}\n\nfunction parseJsonValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value)\n } catch {\n throw new DatabricksSqlError('Failed to parse JSON value', 'INVALID_JSON')\n }\n }\n\n return value\n}\n\nfunction convertNumber(value: unknown): unknown {\n if (typeof value === 'number')\n return value\n\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? value : parsed\n }\n\n return value\n}\n\nfunction convertInteger(value: unknown): unknown {\n if (typeof value === 'bigint')\n return value\n\n if (typeof value === 'number') {\n if (Number.isInteger(value))\n return BigInt(value)\n return value\n }\n\n if (typeof value === 'string') {\n try {\n // Preserve integer semantics for BIGINT/DECIMAL(scale=0) by returning bigint.\n return BigInt(value)\n } catch {\n return value\n }\n }\n\n return value\n}\n\nfunction convertBoolean(value: unknown): unknown {\n if (typeof value === 'boolean')\n return value\n\n if (typeof value === 'string') {\n if (value === 'true') return true\n if (value === 'false') return false\n }\n\n return value\n}\n","import type { MergeFormat } from '@bitofsky/merge-streams'\nimport type {\n AuthInfo,\n ExternalLinkInfo,\n FetchStreamOptions,\n StatementManifest,\n StatementResult,\n} from '../types.js'\n\nimport { PassThrough, Readable } from 'node:stream'\n\nimport { mergeStreamsFromUrls } from '@bitofsky/merge-streams'\n\nimport { getChunk } from '../databricks-api.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { pipeUrlToOutput, validateSucceededResult } from '../util.js'\n\n/**\n * Create a readable stream from statement result.\n * Merges all external link chunks into a single binary stream,\n * preserving the original format (JSON_ARRAY, CSV, ARROW_STREAM).\n */\nexport function fetchStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchStreamOptions = {}\n): Readable {\n const { signal, forceMerge, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const format = manifest.format as MergeFormat\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n\n if (statementResult.result?.data_array) {\n logger?.error?.(\n `fetchStream only supports EXTERNAL_LINKS results for statement ${statementId}.`,\n { ...baseLog, hasDataArray: true }\n )\n throw new DatabricksSqlError(\n 'fetchStream only supports EXTERNAL_LINKS results',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchStream creating stream for statement ${statementId}.`, {\n ...baseLog,\n hasExternalLinks: Boolean(statementResult.result?.external_links?.length),\n })\n\n // Create PassThrough as output (readable by consumer)\n const output = new PassThrough()\n\n // Handle AbortSignal\n if (signal) {\n const onAbort = () => {\n logger?.info?.(`fetchStream abort signal received while streaming statement ${statementId}.`, baseLog)\n output.destroy(new AbortError('Stream aborted'))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n output.once('close', () => signal.removeEventListener('abort', onAbort))\n }\n\n // Prevent AbortError from becoming an uncaught exception when no error handler is attached.\n output.on('error', (err) => {\n if (err instanceof AbortError)\n return\n if (output.listenerCount('error') === 1)\n throw err\n })\n\n // Start async merge process\n // Errors are forwarded to the stream consumer via destroy.\n mergeChunksToStream(statementResult, auth, manifest, format, output, signal, forceMerge, logger)\n .catch((err) => {\n logger?.error?.(`fetchStream error while streaming statement ${statementId}.`, {\n ...baseLog,\n error: err,\n })\n output.destroy(err as Error)\n })\n\n return output\n}\n\n/**\n * Collect all external link URLs and merge them into output stream\n */\nasync function mergeChunksToStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n format: MergeFormat,\n output: PassThrough,\n signal?: AbortSignal,\n forceMerge?: boolean,\n logger?: FetchStreamOptions['logger']\n): Promise<void> {\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n logger?.info?.(`fetchStream collecting external links for statement ${statementId}.`, baseLog)\n const urls = await collectExternalUrls(statementResult, auth, manifest, signal)\n\n // No external links - close the stream\n if (urls.length === 0) {\n logger?.info?.(`fetchStream no external links found for statement ${statementId}.`, baseLog)\n return void output.end()\n }\n\n // Single URL - pipe directly to output unless forcing merge\n if (urls.length === 1 && !forceMerge) {\n logger?.info?.(`fetchStream piping single external link for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n // Avoid merge-streams overhead for a single URL unless forced.\n return pipeUrlToOutput(urls[0]!, output, signal)\n }\n\n // Merge all URLs using merge-streams\n logger?.info?.(`fetchStream merging ${urls.length} external links for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n return mergeStreamsFromUrls(format, signal ? { urls, output, signal } : { urls, output })\n}\n\nasync function collectExternalUrls(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n signal?: AbortSignal\n): Promise<string[]> {\n const chunkUrls = new Map<number, string[]>()\n\n addChunkLinks(chunkUrls, statementResult.result?.external_links)\n\n if (!manifest.total_chunk_count)\n return flattenChunkUrls(chunkUrls)\n\n for (let i = 0; i < manifest.total_chunk_count; i++) {\n if (chunkUrls.has(i))\n continue\n if (signal?.aborted)\n throw new AbortError('Aborted while collecting URLs')\n\n // Chunk metadata contains external link URLs when results are chunked.\n const chunkData = await getChunk(auth, statementResult.statement_id, i, signal)\n addChunkLinks(chunkUrls, chunkData.external_links)\n }\n\n return flattenChunkUrls(chunkUrls)\n}\n\nfunction addChunkLinks(\n chunkUrls: Map<number, string[]>,\n externalLinks?: ExternalLinkInfo[]\n): void {\n if (!externalLinks)\n return\n\n for (const link of externalLinks) {\n if (!isNonEmptyString(link.external_link))\n continue\n\n const existing = chunkUrls.get(link.chunk_index)\n if (existing) {\n existing.push(link.external_link)\n } else {\n chunkUrls.set(link.chunk_index, [link.external_link])\n }\n }\n}\n\nfunction flattenChunkUrls(chunkUrls: Map<number, string[]>): string[] {\n if (chunkUrls.size === 0)\n return []\n\n const sorted = [...chunkUrls.entries()].sort(([a], [b]) => a - b)\n const urls: string[] = []\n for (const [, links] of sorted) {\n urls.push(...links)\n }\n return urls\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n","import type {\n AuthInfo,\n FetchAllOptions,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { fetchRow } from './fetchRow.js'\n\n/**\n * Fetch all rows from statement result as an array.\n * Only supports INLINE results or JSON_ARRAY external links.\n */\nexport async function fetchAll(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchAllOptions = {}\n): Promise<Array<RowArray | RowObject>> {\n const rows: Array<RowArray | RowObject> = []\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const logContext = { statementId, manifest, requestedFormat: options.format }\n const fetchOptions: FetchRowsOptions = {\n // Collect rows as they are streamed in.\n onEachRow: (row) => {\n rows.push(row)\n },\n }\n const { logger } = options\n\n logger?.info?.(`fetchAll fetching all rows for statement ${statementId}.`, logContext)\n\n if (options.signal)\n fetchOptions.signal = options.signal\n\n if (options.format)\n fetchOptions.format = options.format\n\n if (options.logger)\n fetchOptions.logger = options.logger\n\n await fetchRow(statementResult, auth, fetchOptions)\n logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {\n ...logContext,\n rowCount: rows.length,\n resolvedFormat: options.format ?? manifest?.format,\n })\n return rows\n}\n","import type {\n AuthInfo,\n MergeExternalLinksOptions,\n StatementResult,\n} from '../types.js'\n\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Merge external links from StatementResult into a single stream,\n * upload it via the provided callback, and return updated StatementResult.\n *\n * If the result is not external links (inline data or empty), returns the original as-is.\n */\nexport async function mergeExternalLinks(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: MergeExternalLinksOptions\n): Promise<StatementResult> {\n const { signal, mergeStreamToExternalLink, forceMerge, logger } = options\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const externalLinks = statementResult.result?.external_links\n const totalChunks = manifest?.total_chunk_count ?? 0\n const logContext = { statementId, manifest, totalChunks, forceMerge }\n\n // If not external links, return original as-is\n if (!externalLinks) {\n logger?.info?.(`mergeExternalLinks no external links to merge for statement ${statementId}.`, logContext)\n return statementResult\n }\n\n if (!forceMerge) {\n const isSingleChunk = totalChunks <= 1\n\n // Skip merging when a single external link already exists unless forced.\n if (isSingleChunk) {\n logger?.info?.(`mergeExternalLinks skipping merge for single external link in statement ${statementId}.`, {\n ...logContext,\n totalChunks,\n })\n return statementResult\n }\n }\n\n // Get merged stream via fetchStream\n logger?.info?.(`mergeExternalLinks merging external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...forceMerge !== undefined ? { forceMerge } : {},\n ...logger ? { logger } : {},\n })\n\n // Upload via callback\n logger?.info?.(`mergeExternalLinks uploading merged external link for statement ${statementId}.`, logContext)\n const uploadResult = await mergeStreamToExternalLink(stream)\n logger?.info?.(`mergeExternalLinks uploaded merged external link for statement ${statementId}.`, {\n ...logContext,\n byteCount: uploadResult.byte_count,\n expiration: uploadResult.expiration,\n })\n\n // Build updated StatementResult\n // Manifest must exist for external links; validate before constructing new result.\n const validatedManifest = validateSucceededResult(statementResult)\n const totalRowCount = validatedManifest.total_row_count ?? 0\n\n return {\n statement_id: statementResult.statement_id,\n status: statementResult.status,\n manifest: {\n ...validatedManifest,\n total_chunk_count: 1,\n total_byte_count: uploadResult.byte_count,\n chunks: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n },\n ],\n },\n result: {\n external_links: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n external_link: uploadResult.externalLink,\n expiration: uploadResult.expiration,\n },\n ],\n },\n }\n}\n"],"mappings":"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","names":["errorBody","mapped","import_node_stream"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/util.ts","../src/http.ts","../src/databricks-api.ts","../src/api/executeStatement.ts","../src/api/fetchRow.ts","../src/createRowMapper.ts","../src/api/fetchStream.ts","../src/api/fetchAll.ts","../src/api/mergeExternalLinks.ts"],"sourcesContent":["// Types\nexport type * from './types.js'\n\n// Errors\nexport * from './errors.js'\n\n// Core functions\nexport * from './api/index.js'\n","/** Base error for Databricks SQL operations */\nexport class DatabricksSqlError extends Error {\n readonly code: string\n readonly statementId: string | undefined\n\n constructor(message: string, code?: string, statementId?: string) {\n super(message)\n this.name = 'DatabricksSqlError'\n this.code = code ?? 'UNKNOWN_ERROR'\n this.statementId = statementId\n Error.captureStackTrace?.(this, DatabricksSqlError)\n }\n}\n\n/** Error when statement is cancelled */\nexport class StatementCancelledError extends DatabricksSqlError {\n constructor(statementId: string) {\n super(`Statement ${statementId} was cancelled`, 'CANCELLED', statementId)\n this.name = 'StatementCancelledError'\n }\n}\n\n/** Error when operation is aborted via AbortSignal */\nexport class AbortError extends DatabricksSqlError {\n constructor(message: string = 'Operation was aborted') {\n super(message, 'ABORTED')\n this.name = 'AbortError'\n }\n}\n\n/** HTTP error from API calls */\nexport class HttpError extends DatabricksSqlError {\n readonly status: number\n readonly statusText: string\n\n constructor(status: number, statusText: string, message?: string) {\n super(message ?? `HTTP ${status}: ${statusText}`, `HTTP_${status}`)\n this.name = 'HttpError'\n this.status = status\n this.statusText = statusText\n }\n}\n\n/** Authentication error (401) */\nexport class AuthenticationError extends HttpError {\n constructor() {\n super(401, 'Unauthorized', 'Authentication failed. Check your token.')\n this.name = 'AuthenticationError'\n }\n}\n\n/** Rate limit error (429) */\nexport class RateLimitError extends HttpError {\n readonly retryAfter: number | undefined\n\n constructor(retryAfter?: number) {\n super(429, 'Too Many Requests', 'Rate limit exceeded')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n","import { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as WebReadableStream } from 'node:stream/web'\nimport type { StatementResult, StatementManifest } from './types.js'\nimport { AbortError, DatabricksSqlError } from './errors.js'\n\n/**\n * Extract warehouse_id from httpPath\n * @example \"/sql/1.0/warehouses/abc123def456\" -> \"abc123def456\"\n */\nexport function extractWarehouseId(httpPath: string): string {\n const match = httpPath.match(/\\/sql\\/\\d+\\.\\d+\\/warehouses\\/([a-zA-Z0-9]+)/)\n if (!match?.[1])\n throw new Error(`Cannot extract warehouse_id from httpPath: ${httpPath}`)\n return match[1]\n}\n\n/**\n * Throw AbortError if signal is aborted\n */\nexport function throwIfAborted(signal: AbortSignal | undefined, context: string): void {\n if (signal?.aborted)\n throw new AbortError(`[${context}] Aborted`)\n}\n\n/**\n * Delay for specified milliseconds with AbortSignal support\n */\nexport async function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted)\n return reject(new AbortError('Aborted before delay'))\n\n let settled = false\n\n const onAbort = () => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n reject(new AbortError('Aborted during delay'))\n }\n\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * Build full URL from host and path\n */\nexport function buildUrl(host: string, path: string): string {\n const base = host.startsWith('https://') ? host : `https://${host}`\n return new URL(path, base).href\n}\n\n/**\n * Validate statement result is in SUCCEEDED state with manifest.\n * Returns the manifest for convenience.\n * @throws {DatabricksSqlError} If state is not SUCCEEDED or manifest is missing\n */\nexport function validateSucceededResult(\n statementResult: StatementResult\n): StatementManifest {\n if (statementResult.status.state !== 'SUCCEEDED')\n throw new DatabricksSqlError(\n `Cannot fetch from non-succeeded statement: ${statementResult.status.state}`,\n 'INVALID_STATE',\n statementResult.statement_id\n )\n\n if (!statementResult.manifest)\n throw new DatabricksSqlError(\n 'Statement result has no manifest',\n 'MISSING_MANIFEST',\n statementResult.statement_id\n )\n\n return statementResult.manifest\n}\n\nfunction isWebReadableStream(body: unknown): body is WebReadableStream {\n return typeof (body as WebReadableStream).getReader === 'function'\n}\n\nexport async function pipeUrlToOutput(\n url: string,\n output: NodeJS.WritableStream,\n signal?: AbortSignal\n): Promise<void> {\n // Uses Node 20+ global fetch with Web streams.\n if (signal?.aborted)\n throw new AbortError('Aborted while streaming')\n\n const response = await fetch(url, signal ? { signal } : undefined)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch external link: ${response.status} ${response.statusText}`\n )\n }\n\n if (!response.body)\n return void output.end()\n\n const body = response.body\n const input = isWebReadableStream(body)\n ? Readable.fromWeb(body)\n : (body as NodeJS.ReadableStream)\n\n await pipeline(input, output)\n}\n","import type { AuthInfo } from './types.js'\nimport {\n HttpError,\n AuthenticationError,\n RateLimitError,\n AbortError,\n} from './errors.js'\nimport { buildUrl, delay } from './util.js'\n\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY_MS = 1000\n\ntype HttpMethod = 'GET' | 'POST' | 'DELETE'\n\ntype HttpRequestOptions = {\n method: HttpMethod\n path: string\n body?: unknown\n signal?: AbortSignal\n}\n\n/**\n * HTTP request wrapper with retry and error handling\n */\nexport async function httpRequest<T>(\n auth: AuthInfo,\n options: HttpRequestOptions\n): Promise<T> {\n const { method, path, body, signal } = options\n const url = buildUrl(auth.host, path)\n\n let lastError: Error | undefined\n let retryDelay = INITIAL_RETRY_DELAY_MS\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n if (signal?.aborted)\n throw new AbortError()\n\n try {\n // Build a minimal fetch init, skipping undefined values.\n const fetchInit = Object.fromEntries(\n Object.entries({\n method,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n }).filter(([, v]) => v !== undefined)\n ) as RequestInit\n\n const response = await fetch(url, fetchInit)\n\n // Success\n if (response.ok)\n return (await response.json()) as T\n\n // Authentication error (no retry)\n if (response.status === 401)\n throw new AuthenticationError()\n\n // Rate limit\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get('Retry-After')\n const retryAfter = retryAfterHeader\n ? parseInt(retryAfterHeader, 10)\n : undefined\n const error = new RateLimitError(\n isNaN(retryAfter as number) ? undefined : retryAfter\n )\n\n if (error.retryAfter && attempt < MAX_RETRIES) {\n await delay(error.retryAfter * 1000, signal)\n continue\n }\n\n throw error\n }\n\n // Server error (can retry)\n if (response.status >= 500) {\n const errorBody = await response.text().catch(() => '')\n lastError = new HttpError(response.status, response.statusText, errorBody)\n\n if (attempt < MAX_RETRIES) {\n // Exponential backoff for transient server errors.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n // Other client errors\n const errorBody = await response.text().catch(() => '')\n\n throw new HttpError(response.status, response.statusText, errorBody)\n\n } catch (err) {\n // Re-throw known errors\n if (\n err instanceof AbortError ||\n err instanceof AuthenticationError ||\n err instanceof HttpError\n )\n throw err\n\n // Network error\n if (err instanceof TypeError && err.message.includes('fetch')) {\n lastError = err\n if (attempt < MAX_RETRIES) {\n // Network errors are retried with backoff.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n throw err\n }\n }\n\n throw lastError ?? new Error('Request failed after retries')\n}\n","import type {\n AuthInfo,\n ExecuteStatementRequest,\n StatementResult,\n GetChunkResponse,\n QueryInfo,\n} from './types.js'\nimport { httpRequest } from './http.js'\n\n// Base path for Databricks SQL Statement Execution API.\nconst BASE_PATH = '/api/2.0/sql/statements'\n// Base path for Query History API.\nconst HISTORY_BASE_PATH = '/api/2.0/sql/history/queries'\n\n/**\n * Execute SQL statement\n * POST /api/2.0/sql/statements\n */\nexport async function postStatement(\n auth: AuthInfo,\n request: ExecuteStatementRequest,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'POST',\n path: BASE_PATH,\n body: request,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get statement status and result\n * GET /api/2.0/sql/statements/{statement_id}\n */\nexport async function getStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Cancel statement execution\n * POST /api/2.0/sql/statements/{statement_id}/cancel\n */\nexport async function cancelStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<void> {\n await httpRequest<unknown>(auth, {\n method: 'POST',\n path: `${BASE_PATH}/${statementId}/cancel`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get result chunk by index\n * GET /api/2.0/sql/statements/{statement_id}/result/chunks/{chunk_index}\n */\nexport async function getChunk(\n auth: AuthInfo,\n statementId: string,\n chunkIndex: number,\n signal?: AbortSignal\n): Promise<GetChunkResponse> {\n return httpRequest<GetChunkResponse>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}/result/chunks/${chunkIndex}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get query metrics from Query History API\n * GET /api/2.0/sql/history/queries/{query_id}?include_metrics=true\n */\nexport async function getQueryMetrics(\n auth: AuthInfo,\n queryId: string,\n signal?: AbortSignal\n): Promise<QueryInfo> {\n return httpRequest<QueryInfo>(auth, {\n method: 'GET',\n path: `${HISTORY_BASE_PATH}/${queryId}?include_metrics=true`,\n ...(signal ? { signal } : {}),\n })\n}\n","import type {\n AuthInfo,\n ExecuteStatementOptions,\n ExecuteStatementRequest,\n StatementResult,\n StatementState,\n QueryMetrics,\n} from '../types.js'\nimport { postStatement, getStatement, cancelStatement, getQueryMetrics } from '../databricks-api.js'\nimport { extractWarehouseId, throwIfAborted, delay } from '../util.js'\nimport {\n DatabricksSqlError,\n StatementCancelledError,\n AbortError,\n} from '../errors.js'\n\nconst TERMINAL_STATES = new Set<StatementState>([\n 'SUCCEEDED',\n 'FAILED',\n 'CANCELED',\n 'CLOSED',\n])\nconst POLL_INTERVAL_MS = 5000\n\nasync function fetchMetrics(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<QueryMetrics | undefined> {\n const queryInfo = await getQueryMetrics(auth, statementId, signal)\n return queryInfo.metrics\n}\n\n/**\n * Execute SQL statement and poll until completion\n */\nexport async function executeStatement(\n query: string,\n auth: AuthInfo,\n options: ExecuteStatementOptions = {}\n): Promise<StatementResult> {\n const warehouseId = options.warehouse_id ?? extractWarehouseId(auth.httpPath)\n const { signal, onProgress, enableMetrics, logger } = options\n const waitTimeout = options.wait_timeout ?? (onProgress ? '0s' : '50s')\n let cancelIssued = false\n\n // Check if already aborted\n throwIfAborted(signal, 'executeStatement')\n\n // Helper to call onProgress with optional metrics\n const emitProgress = onProgress\n ? async () => result ? onProgress(\n result,\n enableMetrics ? await fetchMetrics(auth, result.statement_id, signal).catch(e => {\n logger?.error?.(`executeStatement Failed to fetch query metrics for statement ${result?.statement_id}: ${String(e)}`, { statementId: result?.statement_id })\n return undefined\n }) : undefined\n ) : undefined\n : undefined\n\n // 1. Build request (filter out undefined values)\n const request = Object.fromEntries(\n Object.entries({\n warehouse_id: warehouseId,\n statement: query,\n byte_limit: options.byte_limit,\n disposition: options.disposition,\n format: options.format,\n on_wait_timeout: options.on_wait_timeout ?? 'CONTINUE',\n wait_timeout: waitTimeout,\n row_limit: options.row_limit,\n catalog: options.catalog,\n schema: options.schema,\n parameters: options.parameters,\n }).filter(([, v]) => v !== undefined)\n ) as ExecuteStatementRequest\n\n logger?.info?.(`executeStatement Executing statement on warehouse ${warehouseId}...`)\n\n // 2. Submit statement execution request\n let result = await postStatement(auth, request, signal)\n const cancelStatementSafely = async () => {\n if (cancelIssued) return\n logger?.info?.('executeStatement Abort signal received during executeStatement.')\n cancelIssued = true\n await cancelStatement(auth, result.statement_id).catch((err) => {\n logger?.error?.('executeStatement Failed to cancel statement after abort.', err)\n })\n }\n\n if (signal?.aborted) {\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n\n const onAbort = () => cancelStatementSafely().catch(() => { })\n\n try {\n signal?.addEventListener('abort', onAbort, { once: true })\n\n // 3. Poll until terminal state\n while (!TERMINAL_STATES.has(result.status.state)) {\n logger?.info?.(`executeStatement Statement ${result.statement_id} in state ${result.status.state}; polling for status...`)\n await delay(POLL_INTERVAL_MS, signal)\n result = await getStatement(auth, result.statement_id, signal)\n await emitProgress?.()\n }\n } catch (err) {\n if (err instanceof AbortError || signal?.aborted) {\n logger?.info?.('executeStatement Abort detected in executeStatement polling loop.')\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n logger?.error?.(`executeStatement Error during executeStatement polling: ${String(err)}`)\n throw err\n } finally {\n logger?.info?.(`executeStatement Statement ${result.statement_id} reached final state: ${result.status.state}`)\n signal?.removeEventListener('abort', onAbort)\n }\n\n // 4. Final progress callback\n await emitProgress?.()\n\n // 5. Handle terminal states\n if (result.status.state === 'SUCCEEDED')\n return result\n\n if (result.status.state === 'CANCELED')\n throw new StatementCancelledError(result.statement_id)\n\n // FAILED or CLOSED\n throw new DatabricksSqlError(\n result.status.error?.message ?? 'Statement execution failed',\n result.status.error?.error_code,\n result.statement_id\n )\n}\n","import type { Readable } from 'node:stream'\nimport type {\n AuthInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { parser } from 'stream-json'\nimport { streamArray } from 'stream-json/streamers/StreamArray'\n\nimport { getChunk } from '../databricks-api.js'\nimport { createRowMapper } from '../createRowMapper.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Process each row from statement result with a callback.\n * Supports INLINE results and JSON_ARRAY external links.\n */\nexport async function fetchRow(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchRowsOptions = {}\n): Promise<void> {\n const { signal, onEachRow, format, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const statementId = statementResult.statement_id\n const logContext = { statementId, manifest, requestedFormat: format }\n // Map JSON_ARRAY rows to JSON_OBJECT when requested.\n const mapRow = createRowMapper(manifest, format, {\n ...options.encodeBigInt ? { encodeBigInt: options.encodeBigInt } : {},\n ...options.encodeTimestamp ? { encodeTimestamp: options.encodeTimestamp } : {},\n })\n\n logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {\n ...logContext,\n resultType: statementResult.result?.external_links ? 'EXTERNAL_LINKS' : 'INLINE',\n })\n\n if (statementResult.result?.external_links) {\n if (manifest.format !== 'JSON_ARRAY') {\n logger?.error?.(`fetchRow only supports JSON_ARRAY for external_links; got ${manifest.format}.`, logContext)\n throw new DatabricksSqlError(\n `fetchRow only supports JSON_ARRAY for external_links. Received: ${manifest.format}`,\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchRow streaming external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...logger ? { logger } : {},\n })\n await consumeJsonArrayStream(stream, mapRow, onEachRow, signal, logger, logContext)\n return\n }\n\n const totalChunks = manifest.total_chunk_count\n\n // Process first chunk (inline data_array)\n const dataArray = statementResult.result?.data_array\n if (dataArray) {\n logger?.info?.(`fetchRow processing inline rows for statement ${statementId}.`, {\n ...logContext,\n inlineRows: dataArray.length,\n })\n for (const row of dataArray) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Convert row to requested shape before callback.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n\n // Process additional chunks if any\n if (totalChunks > 1) {\n logger?.info?.(`fetchRow processing ${totalChunks} chunks for statement ${statementId}.`, logContext)\n for (let chunkIndex = 1; chunkIndex < totalChunks; chunkIndex++) {\n if (signal?.aborted) throw new AbortError('Aborted')\n\n const chunk = await getChunk(auth, statementId, chunkIndex, signal)\n\n // Additional chunks should also be data_array (INLINE)\n if (chunk.external_links)\n throw new DatabricksSqlError(\n 'fetchRow only supports INLINE results. Chunk contains external_links.',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n\n if (chunk.data_array) {\n for (const row of chunk.data_array) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Apply the same mapping for each chunked row.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n }\n }\n}\n\nasync function consumeJsonArrayStream(\n stream: Readable,\n mapRow: (row: RowArray) => RowArray | RowObject,\n onEachRow: ((row: RowArray | RowObject) => void) | undefined,\n signal: AbortSignal | undefined,\n logger: FetchRowsOptions['logger'],\n logContext: Record<string, unknown>\n): Promise<void> {\n // Stream JSON_ARRAY as individual rows to avoid buffering whole payloads.\n const jsonStream = stream.pipe(parser()).pipe(streamArray())\n\n for await (const item of jsonStream) {\n if (signal?.aborted) {\n logger?.info?.('fetchRow abort detected while streaming JSON_ARRAY rows.', {\n ...logContext,\n aborted: signal.aborted,\n })\n stream.destroy(new AbortError('Aborted'))\n throw new AbortError('Aborted')\n }\n\n const row = item.value\n if (!Array.isArray(row)) {\n throw new DatabricksSqlError(\n 'Expected JSON_ARRAY rows to be arrays',\n 'INVALID_FORMAT'\n )\n }\n\n onEachRow?.(mapRow(row))\n }\n}\n","import { DatabricksSqlError } from './errors.js'\nimport type {\n ColumnInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n RowMapperOptions,\n StatementManifest,\n} from './types.js'\n\ntype RowMapper = (row: RowArray) => RowArray | RowObject\n\ntype TypeDescriptor = {\n typeName: string\n typeText: string\n precision?: number\n scale?: number\n fields?: StructField[]\n elementType?: TypeDescriptor\n keyType?: TypeDescriptor\n valueType?: TypeDescriptor\n}\n\ntype StructField = {\n name: string\n type: TypeDescriptor\n}\n\n// Type buckets used for value conversion decisions.\nconst INTEGER_TYPES = new Set(['TINYINT', 'SMALLINT', 'INT'])\nconst BIGINT_TYPES = new Set(['BIGINT', 'LONG'])\nconst FLOAT_TYPES = new Set(['FLOAT', 'DOUBLE'])\nconst BOOLEAN_TYPES = new Set(['BOOLEAN'])\nconst TIMESTAMP_TYPES = new Set(['TIMESTAMP', 'TIMESTAMP_NTZ', 'TIMESTAMP_LTZ'])\nconst STRING_TYPES = new Set([\n 'STRING',\n 'DATE',\n 'TIME',\n])\n\n/**\n * Create a row mapper that converts JSON_ARRAY rows into JSON_OBJECTs.\n * Datetime-like fields are preserved as strings to avoid locale/zone surprises.\n * DECIMAL values are converted to numbers to match the Databricks SDK behavior.\n */\nexport function createRowMapper(\n manifest: StatementManifest,\n format: FetchRowsOptions['format'],\n options: RowMapperOptions = {}\n): RowMapper {\n if (format !== 'JSON_OBJECT')\n return (row) => row\n\n // Precompute per-column converters for fast row mapping.\n const columnConverters = manifest.schema.columns.map((column: ColumnInfo) => ({\n name: column.name,\n convert: createColumnConverter(column, options),\n }))\n\n return (row) => {\n const mapped: RowObject = {}\n for (let index = 0; index < columnConverters.length; index++) {\n const converter = columnConverters[index]\n if (!converter)\n continue\n\n const { name, convert } = converter\n if (name)\n mapped[name] = convert(row[index])\n }\n return mapped\n }\n}\n\nfunction createColumnConverter(\n column: ColumnInfo,\n options: RowMapperOptions\n): (value: unknown) => unknown {\n const descriptor = parseColumnType(column)\n return (value) => convertValue(descriptor, value, options)\n}\n\nfunction parseColumnType(column: ColumnInfo): TypeDescriptor {\n if (column.type_name === 'STRUCT' || column.type_name === 'ARRAY' || column.type_name === 'MAP')\n return parseTypeDescriptor(column.type_text)\n\n if (column.type_name === 'DECIMAL')\n // Prefer precision/scale provided by the API when available.\n return createDecimalDescriptor({\n typeName: column.type_name,\n typeText: column.type_text,\n }, column.type_precision, column.type_scale)\n\n return {\n typeName: column.type_name,\n typeText: column.type_text,\n }\n}\n\nfunction parseTypeDescriptor(typeText: string): TypeDescriptor {\n const trimmed = typeText.trim()\n const typeName = getTypeName(trimmed)\n\n if (typeName === 'STRUCT')\n // STRUCT fields are parsed recursively from type_text.\n return {\n typeName,\n typeText: trimmed,\n fields: parseStructFields(trimmed),\n }\n\n if (typeName === 'ARRAY') {\n const elementTypeText = parseSingleTypeArgument(trimmed)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (elementTypeText)\n descriptor.elementType = parseTypeDescriptor(elementTypeText)\n return descriptor\n }\n\n if (typeName === 'MAP') {\n const [keyTypeText, valueTypeText] = parseTypeArguments(trimmed, 2)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (keyTypeText)\n descriptor.keyType = parseTypeDescriptor(keyTypeText)\n if (valueTypeText)\n descriptor.valueType = parseTypeDescriptor(valueTypeText)\n return descriptor\n }\n\n if (typeName === 'DECIMAL') {\n // DECIMAL(precision, scale) needs explicit parsing for integer conversion.\n const { precision, scale } = parseDecimalInfo(trimmed)\n return createDecimalDescriptor({ typeName, typeText: trimmed }, precision, scale)\n }\n\n return {\n typeName,\n typeText: trimmed,\n }\n}\n\nfunction getTypeName(typeText: string): string {\n return typeText.match(/^[A-Z_]+/)?.[0] ?? typeText\n}\n\nfunction parseDecimalInfo(typeText: string): { precision?: number; scale?: number } {\n const match = typeText.match(/DECIMAL\\((\\d+),\\s*(\\d+)\\)/)\n if (!match)\n return {}\n\n return {\n precision: Number(match[1]),\n scale: Number(match[2]),\n }\n}\n\nfunction createDecimalDescriptor(\n base: Omit<TypeDescriptor, 'precision' | 'scale'>,\n precision?: number,\n scale?: number\n): TypeDescriptor {\n const descriptor: TypeDescriptor = { ...base }\n if (precision !== undefined)\n descriptor.precision = precision\n if (scale !== undefined)\n descriptor.scale = scale\n return descriptor\n}\n\nfunction parseStructFields(typeText: string): StructField[] {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n // Split by commas only at the top level of nested type definitions.\n const parts = splitTopLevel(inner)\n const fields: StructField[] = []\n\n for (const part of parts) {\n const separatorIndex = part.indexOf(':')\n if (separatorIndex === -1)\n continue\n\n const name = part.slice(0, separatorIndex).trim()\n let fieldTypeText = part.slice(separatorIndex + 1).trim()\n fieldTypeText = stripNotNull(fieldTypeText)\n\n if (!name)\n continue\n\n fields.push({\n name,\n type: parseTypeDescriptor(fieldTypeText),\n })\n }\n\n return fields\n}\n\nfunction parseSingleTypeArgument(typeText: string): string | null {\n const [arg] = parseTypeArguments(typeText, 1)\n return arg ?? null\n}\n\nfunction parseTypeArguments(typeText: string, expectedCount: number): Array<string | undefined> {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n const parts = splitTopLevel(inner)\n if (parts.length < expectedCount)\n return parts\n\n return parts.slice(0, expectedCount).map((part) => stripNotNull(part.trim()))\n}\n\nfunction splitTopLevel(value: string): string[] {\n const result: string[] = []\n let current = ''\n let angleDepth = 0\n let parenDepth = 0\n\n for (const char of value) {\n if (char === '<') angleDepth++\n if (char === '>') angleDepth--\n if (char === '(') parenDepth++\n if (char === ')') parenDepth--\n\n if (char === ',' && angleDepth === 0 && parenDepth === 0) {\n result.push(current.trim())\n current = ''\n continue\n }\n\n current += char\n }\n\n if (current.trim().length > 0)\n result.push(current.trim())\n\n return result\n}\n\nfunction stripNotNull(typeText: string): string {\n let trimmed = typeText.trim()\n while (trimmed.endsWith('NOT NULL'))\n trimmed = trimmed.slice(0, -'NOT NULL'.length).trim()\n return trimmed\n}\n\nfunction convertValue(\n descriptor: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n if (value === null || value === undefined)\n return value\n\n if (descriptor.typeName === 'STRUCT' && descriptor.fields)\n // STRUCT values are JSON strings in JSON_ARRAY format.\n return convertStructValue(descriptor.fields, value, options)\n\n if (descriptor.typeName === 'ARRAY' && descriptor.elementType)\n return convertArrayValue(descriptor.elementType, value, options)\n\n if (descriptor.typeName === 'MAP' && descriptor.keyType && descriptor.valueType)\n return convertMapValue(descriptor.keyType, descriptor.valueType, value, options)\n\n if (descriptor.typeName === 'DECIMAL')\n return convertNumber(value)\n\n if (INTEGER_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BIGINT_TYPES.has(descriptor.typeName))\n return convertInteger(value, options.encodeBigInt)\n\n if (FLOAT_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BOOLEAN_TYPES.has(descriptor.typeName))\n return convertBoolean(value)\n\n if (TIMESTAMP_TYPES.has(descriptor.typeName))\n return convertTimestamp(value, options.encodeTimestamp)\n\n if (STRING_TYPES.has(descriptor.typeName))\n return value\n\n return value\n}\n\nfunction convertStructValue(\n fields: StructField[],\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseStructValue(value)\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return value\n\n // Apply nested field conversions based on the parsed STRUCT schema.\n const mapped: RowObject = {}\n for (const field of fields)\n mapped[field.name] = convertValue(field.type, (raw as RowObject)[field.name], options)\n\n return mapped\n}\n\nfunction convertArrayValue(\n elementType: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseJsonValue(value)\n if (!Array.isArray(raw))\n return value\n\n return raw.map((entry) => convertValue(elementType, entry, options))\n}\n\nfunction convertMapValue(\n keyType: TypeDescriptor,\n valueType: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseJsonValue(value)\n if (!raw || typeof raw !== 'object')\n return value\n\n if (Array.isArray(raw)) {\n const mapped: RowObject = {}\n for (const entry of raw) {\n if (!Array.isArray(entry) || entry.length < 2)\n continue\n const convertedKey = convertValue(keyType, entry[0], options)\n mapped[String(convertedKey)] = convertValue(valueType, entry[1], options)\n }\n return mapped\n }\n\n const mapped: RowObject = {}\n for (const [key, entryValue] of Object.entries(raw)) {\n const convertedKey = convertValue(keyType, key, options)\n mapped[String(convertedKey)] = convertValue(valueType, entryValue, options)\n }\n\n return mapped\n}\n\nfunction parseStructValue(value: unknown): RowObject | null {\n const parsed = parseJsonValue(value)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed as RowObject\n\n return parsed as RowObject | null\n}\n\nfunction parseJsonValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value)\n } catch {\n throw new DatabricksSqlError('Failed to parse JSON value', 'INVALID_JSON')\n }\n }\n\n return value\n}\n\nfunction convertNumber(value: unknown): unknown {\n if (typeof value === 'number')\n return value\n\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? value : parsed\n }\n\n return value\n}\n\nfunction convertInteger(value: unknown, encodeBigInt?: (value: bigint) => unknown): unknown {\n if (typeof value === 'bigint')\n return encodeBigInt ? encodeBigInt(value) : value\n\n if (typeof value === 'number') {\n if (Number.isInteger(value)) {\n const bigintValue = BigInt(value)\n return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue\n }\n return value\n }\n\n if (typeof value === 'string') {\n try {\n // Preserve integer semantics for BIGINT/DECIMAL(scale=0) by returning bigint.\n const bigintValue = BigInt(value)\n return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue\n } catch {\n return value\n }\n }\n\n return value\n}\n\nfunction convertTimestamp(\n value: unknown,\n encodeTimestamp?: (value: string) => unknown\n): unknown {\n if (typeof value !== 'string')\n return value\n\n return encodeTimestamp ? encodeTimestamp(value) : value\n}\n\nfunction convertBoolean(value: unknown): unknown {\n if (typeof value === 'boolean')\n return value\n\n if (typeof value === 'string') {\n if (value === 'true') return true\n if (value === 'false') return false\n }\n\n return value\n}\n","import type { MergeFormat } from '@bitofsky/merge-streams'\nimport type {\n AuthInfo,\n ExternalLinkInfo,\n FetchStreamOptions,\n StatementManifest,\n StatementResult,\n} from '../types.js'\n\nimport { PassThrough, Readable } from 'node:stream'\n\nimport { mergeStreamsFromUrls } from '@bitofsky/merge-streams'\n\nimport { getChunk } from '../databricks-api.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { pipeUrlToOutput, validateSucceededResult } from '../util.js'\n\n/**\n * Create a readable stream from statement result.\n * Merges all external link chunks into a single binary stream,\n * preserving the original format (JSON_ARRAY, CSV, ARROW_STREAM).\n */\nexport function fetchStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchStreamOptions = {}\n): Readable {\n const { signal, forceMerge, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const format = manifest.format as MergeFormat\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n\n if (statementResult.result?.data_array) {\n logger?.error?.(\n `fetchStream only supports EXTERNAL_LINKS results for statement ${statementId}.`,\n { ...baseLog, hasDataArray: true }\n )\n throw new DatabricksSqlError(\n 'fetchStream only supports EXTERNAL_LINKS results',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchStream creating stream for statement ${statementId}.`, {\n ...baseLog,\n hasExternalLinks: Boolean(statementResult.result?.external_links?.length),\n })\n\n // Create PassThrough as output (readable by consumer)\n const output = new PassThrough()\n\n // Handle AbortSignal\n if (signal) {\n const onAbort = () => {\n logger?.info?.(`fetchStream abort signal received while streaming statement ${statementId}.`, baseLog)\n output.destroy(new AbortError('Stream aborted'))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n output.once('close', () => signal.removeEventListener('abort', onAbort))\n }\n\n // Prevent AbortError from becoming an uncaught exception when no error handler is attached.\n output.on('error', (err) => {\n if (err instanceof AbortError)\n return\n if (output.listenerCount('error') === 1)\n throw err\n })\n\n // Start async merge process\n // Errors are forwarded to the stream consumer via destroy.\n mergeChunksToStream(statementResult, auth, manifest, format, output, signal, forceMerge, logger)\n .catch((err) => {\n logger?.error?.(`fetchStream error while streaming statement ${statementId}.`, {\n ...baseLog,\n error: err,\n })\n output.destroy(err as Error)\n })\n\n return output\n}\n\n/**\n * Collect all external link URLs and merge them into output stream\n */\nasync function mergeChunksToStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n format: MergeFormat,\n output: PassThrough,\n signal?: AbortSignal,\n forceMerge?: boolean,\n logger?: FetchStreamOptions['logger']\n): Promise<void> {\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n logger?.info?.(`fetchStream collecting external links for statement ${statementId}.`, baseLog)\n const urls = await collectExternalUrls(statementResult, auth, manifest, signal)\n\n // No external links - close the stream\n if (urls.length === 0) {\n logger?.info?.(`fetchStream no external links found for statement ${statementId}.`, baseLog)\n return void output.end()\n }\n\n // Single URL - pipe directly to output unless forcing merge\n if (urls.length === 1 && !forceMerge) {\n logger?.info?.(`fetchStream piping single external link for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n // Avoid merge-streams overhead for a single URL unless forced.\n return pipeUrlToOutput(urls[0]!, output, signal)\n }\n\n // Merge all URLs using merge-streams\n logger?.info?.(`fetchStream merging ${urls.length} external links for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n return mergeStreamsFromUrls(format, signal ? { urls, output, signal } : { urls, output })\n}\n\nasync function collectExternalUrls(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n signal?: AbortSignal\n): Promise<string[]> {\n const chunkUrls = new Map<number, string[]>()\n\n addChunkLinks(chunkUrls, statementResult.result?.external_links)\n\n if (!manifest.total_chunk_count)\n return flattenChunkUrls(chunkUrls)\n\n for (let i = 0; i < manifest.total_chunk_count; i++) {\n if (chunkUrls.has(i))\n continue\n if (signal?.aborted)\n throw new AbortError('Aborted while collecting URLs')\n\n // Chunk metadata contains external link URLs when results are chunked.\n const chunkData = await getChunk(auth, statementResult.statement_id, i, signal)\n addChunkLinks(chunkUrls, chunkData.external_links)\n }\n\n return flattenChunkUrls(chunkUrls)\n}\n\nfunction addChunkLinks(\n chunkUrls: Map<number, string[]>,\n externalLinks?: ExternalLinkInfo[]\n): void {\n if (!externalLinks)\n return\n\n for (const link of externalLinks) {\n if (!isNonEmptyString(link.external_link))\n continue\n\n const existing = chunkUrls.get(link.chunk_index)\n if (existing) {\n existing.push(link.external_link)\n } else {\n chunkUrls.set(link.chunk_index, [link.external_link])\n }\n }\n}\n\nfunction flattenChunkUrls(chunkUrls: Map<number, string[]>): string[] {\n if (chunkUrls.size === 0)\n return []\n\n const sorted = [...chunkUrls.entries()].sort(([a], [b]) => a - b)\n const urls: string[] = []\n for (const [, links] of sorted) {\n urls.push(...links)\n }\n return urls\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n","import type {\n AuthInfo,\n FetchAllOptions,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { fetchRow } from './fetchRow.js'\n\n/**\n * Fetch all rows from statement result as an array.\n * Only supports INLINE results or JSON_ARRAY external links.\n */\nexport async function fetchAll(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchAllOptions = {}\n): Promise<Array<RowArray | RowObject>> {\n const rows: Array<RowArray | RowObject> = []\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const logContext = { statementId, manifest, requestedFormat: options.format }\n const fetchOptions: FetchRowsOptions = {\n // Collect rows as they are streamed in.\n onEachRow: (row) => {\n rows.push(row)\n },\n }\n const { logger } = options\n\n logger?.info?.(`fetchAll fetching all rows for statement ${statementId}.`, logContext)\n\n if (options.signal)\n fetchOptions.signal = options.signal\n\n if (options.format)\n fetchOptions.format = options.format\n\n if (options.logger)\n fetchOptions.logger = options.logger\n\n if (options.encodeBigInt)\n fetchOptions.encodeBigInt = options.encodeBigInt\n\n if (options.encodeTimestamp)\n fetchOptions.encodeTimestamp = options.encodeTimestamp\n\n await fetchRow(statementResult, auth, fetchOptions)\n logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {\n ...logContext,\n rowCount: rows.length,\n resolvedFormat: options.format ?? manifest?.format,\n })\n return rows\n}\n","import type {\n AuthInfo,\n MergeExternalLinksOptions,\n StatementResult,\n} from '../types.js'\n\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Merge external links from StatementResult into a single stream,\n * upload it via the provided callback, and return updated StatementResult.\n *\n * If the result is not external links (inline data or empty), returns the original as-is.\n */\nexport async function mergeExternalLinks(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: MergeExternalLinksOptions\n): Promise<StatementResult> {\n const { signal, mergeStreamToExternalLink, forceMerge, logger } = options\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const externalLinks = statementResult.result?.external_links\n const totalChunks = manifest?.total_chunk_count ?? 0\n const logContext = { statementId, manifest, totalChunks, forceMerge }\n\n // If not external links, return original as-is\n if (!externalLinks) {\n logger?.info?.(`mergeExternalLinks no external links to merge for statement ${statementId}.`, logContext)\n return statementResult\n }\n\n if (!forceMerge) {\n const isSingleChunk = totalChunks <= 1\n\n // Skip merging when a single external link already exists unless forced.\n if (isSingleChunk) {\n logger?.info?.(`mergeExternalLinks skipping merge for single external link in statement ${statementId}.`, {\n ...logContext,\n totalChunks,\n })\n return statementResult\n }\n }\n\n // Get merged stream via fetchStream\n logger?.info?.(`mergeExternalLinks merging external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...forceMerge !== undefined ? { forceMerge } : {},\n ...logger ? { logger } : {},\n })\n\n // Upload via callback\n logger?.info?.(`mergeExternalLinks uploading merged external link for statement ${statementId}.`, logContext)\n const uploadResult = await mergeStreamToExternalLink(stream)\n logger?.info?.(`mergeExternalLinks uploaded merged external link for statement ${statementId}.`, {\n ...logContext,\n byteCount: uploadResult.byte_count,\n expiration: uploadResult.expiration,\n })\n\n // Build updated StatementResult\n // Manifest must exist for external links; validate before constructing new result.\n const validatedManifest = validateSucceededResult(statementResult)\n const totalRowCount = validatedManifest.total_row_count ?? 0\n\n return {\n statement_id: statementResult.statement_id,\n status: statementResult.status,\n manifest: {\n ...validatedManifest,\n total_chunk_count: 1,\n total_byte_count: uploadResult.byte_count,\n chunks: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n },\n ],\n },\n result: {\n external_links: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n external_link: uploadResult.externalLink,\n expiration: uploadResult.expiration,\n },\n ],\n },\n }\n}\n"],"mappings":"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","names":["errorBody","mapped","import_node_stream"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -210,6 +210,13 @@ type SignalOptions = {
|
|
|
210
210
|
type RowArray = unknown[];
|
|
211
211
|
/** Row data as JSON object */
|
|
212
212
|
type RowObject = Record<string, unknown>;
|
|
213
|
+
/** Options for row mapping */
|
|
214
|
+
type RowMapperOptions = {
|
|
215
|
+
/** Hook to transform bigint values (e.g., to string or number) */
|
|
216
|
+
encodeBigInt?: (value: bigint) => unknown;
|
|
217
|
+
/** Hook to transform timestamp-like values (e.g., to Date) */
|
|
218
|
+
encodeTimestamp?: (value: string) => unknown;
|
|
219
|
+
};
|
|
213
220
|
/** Format for fetchRow/fetchAll */
|
|
214
221
|
type FetchRowFormat = 'JSON_ARRAY' | 'JSON_OBJECT';
|
|
215
222
|
/** Options for fetchStream */
|
|
@@ -221,12 +228,16 @@ type FetchStreamOptions = SignalOptions & {
|
|
|
221
228
|
};
|
|
222
229
|
/** Options for fetchRow */
|
|
223
230
|
type FetchRowsOptions = SignalOptions & {
|
|
224
|
-
/** Callback for each row */
|
|
225
|
-
onEachRow?: (row: RowArray | RowObject) => void;
|
|
226
231
|
/** Row format (default: JSON_ARRAY) */
|
|
227
232
|
format?: FetchRowFormat;
|
|
228
233
|
/** Optional logger for lifecycle events */
|
|
229
234
|
logger?: Logger;
|
|
235
|
+
/** Callback for each row */
|
|
236
|
+
onEachRow?: (row: RowArray | RowObject) => void;
|
|
237
|
+
/** Customize bigint conversion for JSON_OBJECT rows */
|
|
238
|
+
encodeBigInt?: RowMapperOptions['encodeBigInt'];
|
|
239
|
+
/** Customize TIMESTAMP* conversion for JSON_OBJECT rows */
|
|
240
|
+
encodeTimestamp?: RowMapperOptions['encodeTimestamp'];
|
|
230
241
|
};
|
|
231
242
|
/** Options for fetchAll */
|
|
232
243
|
type FetchAllOptions = SignalOptions & {
|
|
@@ -234,6 +245,10 @@ type FetchAllOptions = SignalOptions & {
|
|
|
234
245
|
format?: FetchRowFormat;
|
|
235
246
|
/** Optional logger for lifecycle events */
|
|
236
247
|
logger?: Logger;
|
|
248
|
+
/** Customize bigint conversion for JSON_OBJECT rows */
|
|
249
|
+
encodeBigInt?: RowMapperOptions['encodeBigInt'];
|
|
250
|
+
/** Customize TIMESTAMP* conversion for JSON_OBJECT rows */
|
|
251
|
+
encodeTimestamp?: RowMapperOptions['encodeTimestamp'];
|
|
237
252
|
};
|
|
238
253
|
/** Result from mergeStreamToExternalLink callback */
|
|
239
254
|
type MergeExternalLinksResult = {
|
|
@@ -346,4 +361,4 @@ declare function fetchStream(statementResult: StatementResult, auth: AuthInfo, o
|
|
|
346
361
|
*/
|
|
347
362
|
declare function mergeExternalLinks(statementResult: StatementResult, auth: AuthInfo, options: MergeExternalLinksOptions): Promise<StatementResult>;
|
|
348
363
|
|
|
349
|
-
export { AbortError, type AuthInfo, AuthenticationError, type ChunkInfo, type ColumnInfo, DatabricksSqlError, type ExecuteStatementOptions, type ExecuteStatementRequest, type ExternalLinkInfo, type ExternalLinksResultData, type FetchAllOptions, type FetchRowFormat, type FetchRowsOptions, type FetchStreamOptions, type GetChunkResponse, HttpError, type InlineResultData, type Logger, type MergeExternalLinksOptions, type MergeExternalLinksResult, type QueryInfo, type QueryMetrics, RateLimitError, type ResultData, type RowArray, type RowObject, type SignalOptions, StatementCancelledError, type StatementManifest, type StatementParameter, type StatementResult, type StatementState, type StatementStatus, executeStatement, fetchAll, fetchRow, fetchStream, mergeExternalLinks };
|
|
364
|
+
export { AbortError, type AuthInfo, AuthenticationError, type ChunkInfo, type ColumnInfo, DatabricksSqlError, type ExecuteStatementOptions, type ExecuteStatementRequest, type ExternalLinkInfo, type ExternalLinksResultData, type FetchAllOptions, type FetchRowFormat, type FetchRowsOptions, type FetchStreamOptions, type GetChunkResponse, HttpError, type InlineResultData, type Logger, type MergeExternalLinksOptions, type MergeExternalLinksResult, type QueryInfo, type QueryMetrics, RateLimitError, type ResultData, type RowArray, type RowMapperOptions, type RowObject, type SignalOptions, StatementCancelledError, type StatementManifest, type StatementParameter, type StatementResult, type StatementState, type StatementStatus, executeStatement, fetchAll, fetchRow, fetchStream, mergeExternalLinks };
|
package/dist/index.d.ts
CHANGED
|
@@ -210,6 +210,13 @@ type SignalOptions = {
|
|
|
210
210
|
type RowArray = unknown[];
|
|
211
211
|
/** Row data as JSON object */
|
|
212
212
|
type RowObject = Record<string, unknown>;
|
|
213
|
+
/** Options for row mapping */
|
|
214
|
+
type RowMapperOptions = {
|
|
215
|
+
/** Hook to transform bigint values (e.g., to string or number) */
|
|
216
|
+
encodeBigInt?: (value: bigint) => unknown;
|
|
217
|
+
/** Hook to transform timestamp-like values (e.g., to Date) */
|
|
218
|
+
encodeTimestamp?: (value: string) => unknown;
|
|
219
|
+
};
|
|
213
220
|
/** Format for fetchRow/fetchAll */
|
|
214
221
|
type FetchRowFormat = 'JSON_ARRAY' | 'JSON_OBJECT';
|
|
215
222
|
/** Options for fetchStream */
|
|
@@ -221,12 +228,16 @@ type FetchStreamOptions = SignalOptions & {
|
|
|
221
228
|
};
|
|
222
229
|
/** Options for fetchRow */
|
|
223
230
|
type FetchRowsOptions = SignalOptions & {
|
|
224
|
-
/** Callback for each row */
|
|
225
|
-
onEachRow?: (row: RowArray | RowObject) => void;
|
|
226
231
|
/** Row format (default: JSON_ARRAY) */
|
|
227
232
|
format?: FetchRowFormat;
|
|
228
233
|
/** Optional logger for lifecycle events */
|
|
229
234
|
logger?: Logger;
|
|
235
|
+
/** Callback for each row */
|
|
236
|
+
onEachRow?: (row: RowArray | RowObject) => void;
|
|
237
|
+
/** Customize bigint conversion for JSON_OBJECT rows */
|
|
238
|
+
encodeBigInt?: RowMapperOptions['encodeBigInt'];
|
|
239
|
+
/** Customize TIMESTAMP* conversion for JSON_OBJECT rows */
|
|
240
|
+
encodeTimestamp?: RowMapperOptions['encodeTimestamp'];
|
|
230
241
|
};
|
|
231
242
|
/** Options for fetchAll */
|
|
232
243
|
type FetchAllOptions = SignalOptions & {
|
|
@@ -234,6 +245,10 @@ type FetchAllOptions = SignalOptions & {
|
|
|
234
245
|
format?: FetchRowFormat;
|
|
235
246
|
/** Optional logger for lifecycle events */
|
|
236
247
|
logger?: Logger;
|
|
248
|
+
/** Customize bigint conversion for JSON_OBJECT rows */
|
|
249
|
+
encodeBigInt?: RowMapperOptions['encodeBigInt'];
|
|
250
|
+
/** Customize TIMESTAMP* conversion for JSON_OBJECT rows */
|
|
251
|
+
encodeTimestamp?: RowMapperOptions['encodeTimestamp'];
|
|
237
252
|
};
|
|
238
253
|
/** Result from mergeStreamToExternalLink callback */
|
|
239
254
|
type MergeExternalLinksResult = {
|
|
@@ -346,4 +361,4 @@ declare function fetchStream(statementResult: StatementResult, auth: AuthInfo, o
|
|
|
346
361
|
*/
|
|
347
362
|
declare function mergeExternalLinks(statementResult: StatementResult, auth: AuthInfo, options: MergeExternalLinksOptions): Promise<StatementResult>;
|
|
348
363
|
|
|
349
|
-
export { AbortError, type AuthInfo, AuthenticationError, type ChunkInfo, type ColumnInfo, DatabricksSqlError, type ExecuteStatementOptions, type ExecuteStatementRequest, type ExternalLinkInfo, type ExternalLinksResultData, type FetchAllOptions, type FetchRowFormat, type FetchRowsOptions, type FetchStreamOptions, type GetChunkResponse, HttpError, type InlineResultData, type Logger, type MergeExternalLinksOptions, type MergeExternalLinksResult, type QueryInfo, type QueryMetrics, RateLimitError, type ResultData, type RowArray, type RowObject, type SignalOptions, StatementCancelledError, type StatementManifest, type StatementParameter, type StatementResult, type StatementState, type StatementStatus, executeStatement, fetchAll, fetchRow, fetchStream, mergeExternalLinks };
|
|
364
|
+
export { AbortError, type AuthInfo, AuthenticationError, type ChunkInfo, type ColumnInfo, DatabricksSqlError, type ExecuteStatementOptions, type ExecuteStatementRequest, type ExternalLinkInfo, type ExternalLinksResultData, type FetchAllOptions, type FetchRowFormat, type FetchRowsOptions, type FetchStreamOptions, type GetChunkResponse, HttpError, type InlineResultData, type Logger, type MergeExternalLinksOptions, type MergeExternalLinksResult, type QueryInfo, type QueryMetrics, RateLimitError, type ResultData, type RowArray, type RowMapperOptions, type RowObject, type SignalOptions, StatementCancelledError, type StatementManifest, type StatementParameter, type StatementResult, type StatementState, type StatementStatus, executeStatement, fetchAll, fetchRow, fetchStream, mergeExternalLinks };
|
package/dist/index.js
CHANGED
|
@@ -324,20 +324,18 @@ var INTEGER_TYPES = /* @__PURE__ */ new Set(["TINYINT", "SMALLINT", "INT"]);
|
|
|
324
324
|
var BIGINT_TYPES = /* @__PURE__ */ new Set(["BIGINT", "LONG"]);
|
|
325
325
|
var FLOAT_TYPES = /* @__PURE__ */ new Set(["FLOAT", "DOUBLE"]);
|
|
326
326
|
var BOOLEAN_TYPES = /* @__PURE__ */ new Set(["BOOLEAN"]);
|
|
327
|
+
var TIMESTAMP_TYPES = /* @__PURE__ */ new Set(["TIMESTAMP", "TIMESTAMP_NTZ", "TIMESTAMP_LTZ"]);
|
|
327
328
|
var STRING_TYPES = /* @__PURE__ */ new Set([
|
|
328
329
|
"STRING",
|
|
329
330
|
"DATE",
|
|
330
|
-
"TIMESTAMP",
|
|
331
|
-
"TIMESTAMP_NTZ",
|
|
332
|
-
"TIMESTAMP_LTZ",
|
|
333
331
|
"TIME"
|
|
334
332
|
]);
|
|
335
|
-
function createRowMapper(manifest, format) {
|
|
333
|
+
function createRowMapper(manifest, format, options = {}) {
|
|
336
334
|
if (format !== "JSON_OBJECT")
|
|
337
335
|
return (row) => row;
|
|
338
336
|
const columnConverters = manifest.schema.columns.map((column) => ({
|
|
339
337
|
name: column.name,
|
|
340
|
-
convert: createColumnConverter(column)
|
|
338
|
+
convert: createColumnConverter(column, options)
|
|
341
339
|
}));
|
|
342
340
|
return (row) => {
|
|
343
341
|
const mapped = {};
|
|
@@ -352,9 +350,9 @@ function createRowMapper(manifest, format) {
|
|
|
352
350
|
return mapped;
|
|
353
351
|
};
|
|
354
352
|
}
|
|
355
|
-
function createColumnConverter(column) {
|
|
353
|
+
function createColumnConverter(column, options) {
|
|
356
354
|
const descriptor = parseColumnType(column);
|
|
357
|
-
return (value) => convertValue(descriptor, value);
|
|
355
|
+
return (value) => convertValue(descriptor, value, options);
|
|
358
356
|
}
|
|
359
357
|
function parseColumnType(column) {
|
|
360
358
|
if (column.type_name === "STRUCT" || column.type_name === "ARRAY" || column.type_name === "MAP")
|
|
@@ -495,45 +493,47 @@ function stripNotNull(typeText) {
|
|
|
495
493
|
trimmed = trimmed.slice(0, -"NOT NULL".length).trim();
|
|
496
494
|
return trimmed;
|
|
497
495
|
}
|
|
498
|
-
function convertValue(descriptor, value) {
|
|
496
|
+
function convertValue(descriptor, value, options) {
|
|
499
497
|
if (value === null || value === void 0)
|
|
500
498
|
return value;
|
|
501
499
|
if (descriptor.typeName === "STRUCT" && descriptor.fields)
|
|
502
|
-
return convertStructValue(descriptor.fields, value);
|
|
500
|
+
return convertStructValue(descriptor.fields, value, options);
|
|
503
501
|
if (descriptor.typeName === "ARRAY" && descriptor.elementType)
|
|
504
|
-
return convertArrayValue(descriptor.elementType, value);
|
|
502
|
+
return convertArrayValue(descriptor.elementType, value, options);
|
|
505
503
|
if (descriptor.typeName === "MAP" && descriptor.keyType && descriptor.valueType)
|
|
506
|
-
return convertMapValue(descriptor.keyType, descriptor.valueType, value);
|
|
504
|
+
return convertMapValue(descriptor.keyType, descriptor.valueType, value, options);
|
|
507
505
|
if (descriptor.typeName === "DECIMAL")
|
|
508
506
|
return convertNumber(value);
|
|
509
507
|
if (INTEGER_TYPES.has(descriptor.typeName))
|
|
510
508
|
return convertNumber(value);
|
|
511
509
|
if (BIGINT_TYPES.has(descriptor.typeName))
|
|
512
|
-
return convertInteger(value);
|
|
510
|
+
return convertInteger(value, options.encodeBigInt);
|
|
513
511
|
if (FLOAT_TYPES.has(descriptor.typeName))
|
|
514
512
|
return convertNumber(value);
|
|
515
513
|
if (BOOLEAN_TYPES.has(descriptor.typeName))
|
|
516
514
|
return convertBoolean(value);
|
|
515
|
+
if (TIMESTAMP_TYPES.has(descriptor.typeName))
|
|
516
|
+
return convertTimestamp(value, options.encodeTimestamp);
|
|
517
517
|
if (STRING_TYPES.has(descriptor.typeName))
|
|
518
518
|
return value;
|
|
519
519
|
return value;
|
|
520
520
|
}
|
|
521
|
-
function convertStructValue(fields, value) {
|
|
521
|
+
function convertStructValue(fields, value, options) {
|
|
522
522
|
const raw = parseStructValue(value);
|
|
523
523
|
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
524
524
|
return value;
|
|
525
525
|
const mapped = {};
|
|
526
526
|
for (const field of fields)
|
|
527
|
-
mapped[field.name] = convertValue(field.type, raw[field.name]);
|
|
527
|
+
mapped[field.name] = convertValue(field.type, raw[field.name], options);
|
|
528
528
|
return mapped;
|
|
529
529
|
}
|
|
530
|
-
function convertArrayValue(elementType, value) {
|
|
530
|
+
function convertArrayValue(elementType, value, options) {
|
|
531
531
|
const raw = parseJsonValue(value);
|
|
532
532
|
if (!Array.isArray(raw))
|
|
533
533
|
return value;
|
|
534
|
-
return raw.map((entry) => convertValue(elementType, entry));
|
|
534
|
+
return raw.map((entry) => convertValue(elementType, entry, options));
|
|
535
535
|
}
|
|
536
|
-
function convertMapValue(keyType, valueType, value) {
|
|
536
|
+
function convertMapValue(keyType, valueType, value, options) {
|
|
537
537
|
const raw = parseJsonValue(value);
|
|
538
538
|
if (!raw || typeof raw !== "object")
|
|
539
539
|
return value;
|
|
@@ -542,15 +542,15 @@ function convertMapValue(keyType, valueType, value) {
|
|
|
542
542
|
for (const entry of raw) {
|
|
543
543
|
if (!Array.isArray(entry) || entry.length < 2)
|
|
544
544
|
continue;
|
|
545
|
-
const convertedKey = convertValue(keyType, entry[0]);
|
|
546
|
-
mapped2[String(convertedKey)] = convertValue(valueType, entry[1]);
|
|
545
|
+
const convertedKey = convertValue(keyType, entry[0], options);
|
|
546
|
+
mapped2[String(convertedKey)] = convertValue(valueType, entry[1], options);
|
|
547
547
|
}
|
|
548
548
|
return mapped2;
|
|
549
549
|
}
|
|
550
550
|
const mapped = {};
|
|
551
551
|
for (const [key, entryValue] of Object.entries(raw)) {
|
|
552
|
-
const convertedKey = convertValue(keyType, key);
|
|
553
|
-
mapped[String(convertedKey)] = convertValue(valueType, entryValue);
|
|
552
|
+
const convertedKey = convertValue(keyType, key, options);
|
|
553
|
+
mapped[String(convertedKey)] = convertValue(valueType, entryValue, options);
|
|
554
554
|
}
|
|
555
555
|
return mapped;
|
|
556
556
|
}
|
|
@@ -579,23 +579,31 @@ function convertNumber(value) {
|
|
|
579
579
|
}
|
|
580
580
|
return value;
|
|
581
581
|
}
|
|
582
|
-
function convertInteger(value) {
|
|
582
|
+
function convertInteger(value, encodeBigInt) {
|
|
583
583
|
if (typeof value === "bigint")
|
|
584
|
-
return value;
|
|
584
|
+
return encodeBigInt ? encodeBigInt(value) : value;
|
|
585
585
|
if (typeof value === "number") {
|
|
586
|
-
if (Number.isInteger(value))
|
|
587
|
-
|
|
586
|
+
if (Number.isInteger(value)) {
|
|
587
|
+
const bigintValue = BigInt(value);
|
|
588
|
+
return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue;
|
|
589
|
+
}
|
|
588
590
|
return value;
|
|
589
591
|
}
|
|
590
592
|
if (typeof value === "string") {
|
|
591
593
|
try {
|
|
592
|
-
|
|
594
|
+
const bigintValue = BigInt(value);
|
|
595
|
+
return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue;
|
|
593
596
|
} catch {
|
|
594
597
|
return value;
|
|
595
598
|
}
|
|
596
599
|
}
|
|
597
600
|
return value;
|
|
598
601
|
}
|
|
602
|
+
function convertTimestamp(value, encodeTimestamp) {
|
|
603
|
+
if (typeof value !== "string")
|
|
604
|
+
return value;
|
|
605
|
+
return encodeTimestamp ? encodeTimestamp(value) : value;
|
|
606
|
+
}
|
|
599
607
|
function convertBoolean(value) {
|
|
600
608
|
if (typeof value === "boolean")
|
|
601
609
|
return value;
|
|
@@ -725,7 +733,10 @@ async function fetchRow(statementResult, auth, options = {}) {
|
|
|
725
733
|
const manifest = validateSucceededResult(statementResult);
|
|
726
734
|
const statementId = statementResult.statement_id;
|
|
727
735
|
const logContext = { statementId, manifest, requestedFormat: format };
|
|
728
|
-
const mapRow = createRowMapper(manifest, format
|
|
736
|
+
const mapRow = createRowMapper(manifest, format, {
|
|
737
|
+
...options.encodeBigInt ? { encodeBigInt: options.encodeBigInt } : {},
|
|
738
|
+
...options.encodeTimestamp ? { encodeTimestamp: options.encodeTimestamp } : {}
|
|
739
|
+
});
|
|
729
740
|
logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {
|
|
730
741
|
...logContext,
|
|
731
742
|
resultType: statementResult.result?.external_links ? "EXTERNAL_LINKS" : "INLINE"
|
|
@@ -821,6 +832,10 @@ async function fetchAll(statementResult, auth, options = {}) {
|
|
|
821
832
|
fetchOptions.format = options.format;
|
|
822
833
|
if (options.logger)
|
|
823
834
|
fetchOptions.logger = options.logger;
|
|
835
|
+
if (options.encodeBigInt)
|
|
836
|
+
fetchOptions.encodeBigInt = options.encodeBigInt;
|
|
837
|
+
if (options.encodeTimestamp)
|
|
838
|
+
fetchOptions.encodeTimestamp = options.encodeTimestamp;
|
|
824
839
|
await fetchRow(statementResult, auth, fetchOptions);
|
|
825
840
|
logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {
|
|
826
841
|
...logContext,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/util.ts","../src/http.ts","../src/databricks-api.ts","../src/api/executeStatement.ts","../src/api/fetchRow.ts","../src/createRowMapper.ts","../src/api/fetchStream.ts","../src/api/fetchAll.ts","../src/api/mergeExternalLinks.ts"],"sourcesContent":["/** Base error for Databricks SQL operations */\nexport class DatabricksSqlError extends Error {\n readonly code: string\n readonly statementId: string | undefined\n\n constructor(message: string, code?: string, statementId?: string) {\n super(message)\n this.name = 'DatabricksSqlError'\n this.code = code ?? 'UNKNOWN_ERROR'\n this.statementId = statementId\n Error.captureStackTrace?.(this, DatabricksSqlError)\n }\n}\n\n/** Error when statement is cancelled */\nexport class StatementCancelledError extends DatabricksSqlError {\n constructor(statementId: string) {\n super(`Statement ${statementId} was cancelled`, 'CANCELLED', statementId)\n this.name = 'StatementCancelledError'\n }\n}\n\n/** Error when operation is aborted via AbortSignal */\nexport class AbortError extends DatabricksSqlError {\n constructor(message: string = 'Operation was aborted') {\n super(message, 'ABORTED')\n this.name = 'AbortError'\n }\n}\n\n/** HTTP error from API calls */\nexport class HttpError extends DatabricksSqlError {\n readonly status: number\n readonly statusText: string\n\n constructor(status: number, statusText: string, message?: string) {\n super(message ?? `HTTP ${status}: ${statusText}`, `HTTP_${status}`)\n this.name = 'HttpError'\n this.status = status\n this.statusText = statusText\n }\n}\n\n/** Authentication error (401) */\nexport class AuthenticationError extends HttpError {\n constructor() {\n super(401, 'Unauthorized', 'Authentication failed. Check your token.')\n this.name = 'AuthenticationError'\n }\n}\n\n/** Rate limit error (429) */\nexport class RateLimitError extends HttpError {\n readonly retryAfter: number | undefined\n\n constructor(retryAfter?: number) {\n super(429, 'Too Many Requests', 'Rate limit exceeded')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n","import { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as WebReadableStream } from 'node:stream/web'\nimport type { StatementResult, StatementManifest } from './types.js'\nimport { AbortError, DatabricksSqlError } from './errors.js'\n\n/**\n * Extract warehouse_id from httpPath\n * @example \"/sql/1.0/warehouses/abc123def456\" -> \"abc123def456\"\n */\nexport function extractWarehouseId(httpPath: string): string {\n const match = httpPath.match(/\\/sql\\/\\d+\\.\\d+\\/warehouses\\/([a-zA-Z0-9]+)/)\n if (!match?.[1])\n throw new Error(`Cannot extract warehouse_id from httpPath: ${httpPath}`)\n return match[1]\n}\n\n/**\n * Throw AbortError if signal is aborted\n */\nexport function throwIfAborted(signal: AbortSignal | undefined, context: string): void {\n if (signal?.aborted)\n throw new AbortError(`[${context}] Aborted`)\n}\n\n/**\n * Delay for specified milliseconds with AbortSignal support\n */\nexport async function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted)\n return reject(new AbortError('Aborted before delay'))\n\n let settled = false\n\n const onAbort = () => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n reject(new AbortError('Aborted during delay'))\n }\n\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * Build full URL from host and path\n */\nexport function buildUrl(host: string, path: string): string {\n const base = host.startsWith('https://') ? host : `https://${host}`\n return new URL(path, base).href\n}\n\n/**\n * Validate statement result is in SUCCEEDED state with manifest.\n * Returns the manifest for convenience.\n * @throws {DatabricksSqlError} If state is not SUCCEEDED or manifest is missing\n */\nexport function validateSucceededResult(\n statementResult: StatementResult\n): StatementManifest {\n if (statementResult.status.state !== 'SUCCEEDED')\n throw new DatabricksSqlError(\n `Cannot fetch from non-succeeded statement: ${statementResult.status.state}`,\n 'INVALID_STATE',\n statementResult.statement_id\n )\n\n if (!statementResult.manifest)\n throw new DatabricksSqlError(\n 'Statement result has no manifest',\n 'MISSING_MANIFEST',\n statementResult.statement_id\n )\n\n return statementResult.manifest\n}\n\nfunction isWebReadableStream(body: unknown): body is WebReadableStream {\n return typeof (body as WebReadableStream).getReader === 'function'\n}\n\nexport async function pipeUrlToOutput(\n url: string,\n output: NodeJS.WritableStream,\n signal?: AbortSignal\n): Promise<void> {\n // Uses Node 20+ global fetch with Web streams.\n if (signal?.aborted)\n throw new AbortError('Aborted while streaming')\n\n const response = await fetch(url, signal ? { signal } : undefined)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch external link: ${response.status} ${response.statusText}`\n )\n }\n\n if (!response.body)\n return void output.end()\n\n const body = response.body\n const input = isWebReadableStream(body)\n ? Readable.fromWeb(body)\n : (body as NodeJS.ReadableStream)\n\n await pipeline(input, output)\n}\n","import type { AuthInfo } from './types.js'\nimport {\n HttpError,\n AuthenticationError,\n RateLimitError,\n AbortError,\n} from './errors.js'\nimport { buildUrl, delay } from './util.js'\n\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY_MS = 1000\n\ntype HttpMethod = 'GET' | 'POST' | 'DELETE'\n\ntype HttpRequestOptions = {\n method: HttpMethod\n path: string\n body?: unknown\n signal?: AbortSignal\n}\n\n/**\n * HTTP request wrapper with retry and error handling\n */\nexport async function httpRequest<T>(\n auth: AuthInfo,\n options: HttpRequestOptions\n): Promise<T> {\n const { method, path, body, signal } = options\n const url = buildUrl(auth.host, path)\n\n let lastError: Error | undefined\n let retryDelay = INITIAL_RETRY_DELAY_MS\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n if (signal?.aborted)\n throw new AbortError()\n\n try {\n // Build a minimal fetch init, skipping undefined values.\n const fetchInit = Object.fromEntries(\n Object.entries({\n method,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n }).filter(([, v]) => v !== undefined)\n ) as RequestInit\n\n const response = await fetch(url, fetchInit)\n\n // Success\n if (response.ok)\n return (await response.json()) as T\n\n // Authentication error (no retry)\n if (response.status === 401)\n throw new AuthenticationError()\n\n // Rate limit\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get('Retry-After')\n const retryAfter = retryAfterHeader\n ? parseInt(retryAfterHeader, 10)\n : undefined\n const error = new RateLimitError(\n isNaN(retryAfter as number) ? undefined : retryAfter\n )\n\n if (error.retryAfter && attempt < MAX_RETRIES) {\n await delay(error.retryAfter * 1000, signal)\n continue\n }\n\n throw error\n }\n\n // Server error (can retry)\n if (response.status >= 500) {\n const errorBody = await response.text().catch(() => '')\n lastError = new HttpError(response.status, response.statusText, errorBody)\n\n if (attempt < MAX_RETRIES) {\n // Exponential backoff for transient server errors.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n // Other client errors\n const errorBody = await response.text().catch(() => '')\n\n throw new HttpError(response.status, response.statusText, errorBody)\n\n } catch (err) {\n // Re-throw known errors\n if (\n err instanceof AbortError ||\n err instanceof AuthenticationError ||\n err instanceof HttpError\n )\n throw err\n\n // Network error\n if (err instanceof TypeError && err.message.includes('fetch')) {\n lastError = err\n if (attempt < MAX_RETRIES) {\n // Network errors are retried with backoff.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n throw err\n }\n }\n\n throw lastError ?? new Error('Request failed after retries')\n}\n","import type {\n AuthInfo,\n ExecuteStatementRequest,\n StatementResult,\n GetChunkResponse,\n QueryInfo,\n} from './types.js'\nimport { httpRequest } from './http.js'\n\n// Base path for Databricks SQL Statement Execution API.\nconst BASE_PATH = '/api/2.0/sql/statements'\n// Base path for Query History API.\nconst HISTORY_BASE_PATH = '/api/2.0/sql/history/queries'\n\n/**\n * Execute SQL statement\n * POST /api/2.0/sql/statements\n */\nexport async function postStatement(\n auth: AuthInfo,\n request: ExecuteStatementRequest,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'POST',\n path: BASE_PATH,\n body: request,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get statement status and result\n * GET /api/2.0/sql/statements/{statement_id}\n */\nexport async function getStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Cancel statement execution\n * POST /api/2.0/sql/statements/{statement_id}/cancel\n */\nexport async function cancelStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<void> {\n await httpRequest<unknown>(auth, {\n method: 'POST',\n path: `${BASE_PATH}/${statementId}/cancel`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get result chunk by index\n * GET /api/2.0/sql/statements/{statement_id}/result/chunks/{chunk_index}\n */\nexport async function getChunk(\n auth: AuthInfo,\n statementId: string,\n chunkIndex: number,\n signal?: AbortSignal\n): Promise<GetChunkResponse> {\n return httpRequest<GetChunkResponse>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}/result/chunks/${chunkIndex}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get query metrics from Query History API\n * GET /api/2.0/sql/history/queries/{query_id}?include_metrics=true\n */\nexport async function getQueryMetrics(\n auth: AuthInfo,\n queryId: string,\n signal?: AbortSignal\n): Promise<QueryInfo> {\n return httpRequest<QueryInfo>(auth, {\n method: 'GET',\n path: `${HISTORY_BASE_PATH}/${queryId}?include_metrics=true`,\n ...(signal ? { signal } : {}),\n })\n}\n","import type {\n AuthInfo,\n ExecuteStatementOptions,\n ExecuteStatementRequest,\n StatementResult,\n StatementState,\n QueryMetrics,\n} from '../types.js'\nimport { postStatement, getStatement, cancelStatement, getQueryMetrics } from '../databricks-api.js'\nimport { extractWarehouseId, throwIfAborted, delay } from '../util.js'\nimport {\n DatabricksSqlError,\n StatementCancelledError,\n AbortError,\n} from '../errors.js'\n\nconst TERMINAL_STATES = new Set<StatementState>([\n 'SUCCEEDED',\n 'FAILED',\n 'CANCELED',\n 'CLOSED',\n])\nconst POLL_INTERVAL_MS = 5000\n\nasync function fetchMetrics(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<QueryMetrics | undefined> {\n const queryInfo = await getQueryMetrics(auth, statementId, signal)\n return queryInfo.metrics\n}\n\n/**\n * Execute SQL statement and poll until completion\n */\nexport async function executeStatement(\n query: string,\n auth: AuthInfo,\n options: ExecuteStatementOptions = {}\n): Promise<StatementResult> {\n const warehouseId = options.warehouse_id ?? extractWarehouseId(auth.httpPath)\n const { signal, onProgress, enableMetrics, logger } = options\n const waitTimeout = options.wait_timeout ?? (onProgress ? '0s' : '50s')\n let cancelIssued = false\n\n // Check if already aborted\n throwIfAborted(signal, 'executeStatement')\n\n // Helper to call onProgress with optional metrics\n const emitProgress = onProgress\n ? async () => result ? onProgress(\n result,\n enableMetrics ? await fetchMetrics(auth, result.statement_id, signal).catch(e => {\n logger?.error?.(`executeStatement Failed to fetch query metrics for statement ${result?.statement_id}: ${String(e)}`, { statementId: result?.statement_id })\n return undefined\n }) : undefined\n ) : undefined\n : undefined\n\n // 1. Build request (filter out undefined values)\n const request = Object.fromEntries(\n Object.entries({\n warehouse_id: warehouseId,\n statement: query,\n byte_limit: options.byte_limit,\n disposition: options.disposition,\n format: options.format,\n on_wait_timeout: options.on_wait_timeout ?? 'CONTINUE',\n wait_timeout: waitTimeout,\n row_limit: options.row_limit,\n catalog: options.catalog,\n schema: options.schema,\n parameters: options.parameters,\n }).filter(([, v]) => v !== undefined)\n ) as ExecuteStatementRequest\n\n logger?.info?.(`executeStatement Executing statement on warehouse ${warehouseId}...`)\n\n // 2. Submit statement execution request\n let result = await postStatement(auth, request, signal)\n const cancelStatementSafely = async () => {\n if (cancelIssued) return\n logger?.info?.('executeStatement Abort signal received during executeStatement.')\n cancelIssued = true\n await cancelStatement(auth, result.statement_id).catch((err) => {\n logger?.error?.('executeStatement Failed to cancel statement after abort.', err)\n })\n }\n\n if (signal?.aborted) {\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n\n const onAbort = () => cancelStatementSafely().catch(() => { })\n\n try {\n signal?.addEventListener('abort', onAbort, { once: true })\n\n // 3. Poll until terminal state\n while (!TERMINAL_STATES.has(result.status.state)) {\n logger?.info?.(`executeStatement Statement ${result.statement_id} in state ${result.status.state}; polling for status...`)\n await delay(POLL_INTERVAL_MS, signal)\n result = await getStatement(auth, result.statement_id, signal)\n await emitProgress?.()\n }\n } catch (err) {\n if (err instanceof AbortError || signal?.aborted) {\n logger?.info?.('executeStatement Abort detected in executeStatement polling loop.')\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n logger?.error?.(`executeStatement Error during executeStatement polling: ${String(err)}`)\n throw err\n } finally {\n logger?.info?.(`executeStatement Statement ${result.statement_id} reached final state: ${result.status.state}`)\n signal?.removeEventListener('abort', onAbort)\n }\n\n // 4. Final progress callback\n await emitProgress?.()\n\n // 5. Handle terminal states\n if (result.status.state === 'SUCCEEDED')\n return result\n\n if (result.status.state === 'CANCELED')\n throw new StatementCancelledError(result.statement_id)\n\n // FAILED or CLOSED\n throw new DatabricksSqlError(\n result.status.error?.message ?? 'Statement execution failed',\n result.status.error?.error_code,\n result.statement_id\n )\n}\n","import type { Readable } from 'node:stream'\nimport type {\n AuthInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { parser } from 'stream-json'\nimport { streamArray } from 'stream-json/streamers/StreamArray'\n\nimport { getChunk } from '../databricks-api.js'\nimport { createRowMapper } from '../createRowMapper.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Process each row from statement result with a callback.\n * Supports INLINE results and JSON_ARRAY external links.\n */\nexport async function fetchRow(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchRowsOptions = {}\n): Promise<void> {\n const { signal, onEachRow, format, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const statementId = statementResult.statement_id\n const logContext = { statementId, manifest, requestedFormat: format }\n // Map JSON_ARRAY rows to JSON_OBJECT when requested.\n const mapRow = createRowMapper(manifest, format)\n\n logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {\n ...logContext,\n resultType: statementResult.result?.external_links ? 'EXTERNAL_LINKS' : 'INLINE',\n })\n\n if (statementResult.result?.external_links) {\n if (manifest.format !== 'JSON_ARRAY') {\n logger?.error?.(`fetchRow only supports JSON_ARRAY for external_links; got ${manifest.format}.`, logContext)\n throw new DatabricksSqlError(\n `fetchRow only supports JSON_ARRAY for external_links. Received: ${manifest.format}`,\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchRow streaming external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...logger ? { logger } : {},\n })\n await consumeJsonArrayStream(stream, mapRow, onEachRow, signal, logger, logContext)\n return\n }\n\n const totalChunks = manifest.total_chunk_count\n\n // Process first chunk (inline data_array)\n const dataArray = statementResult.result?.data_array\n if (dataArray) {\n logger?.info?.(`fetchRow processing inline rows for statement ${statementId}.`, {\n ...logContext,\n inlineRows: dataArray.length,\n })\n for (const row of dataArray) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Convert row to requested shape before callback.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n\n // Process additional chunks if any\n if (totalChunks > 1) {\n logger?.info?.(`fetchRow processing ${totalChunks} chunks for statement ${statementId}.`, logContext)\n for (let chunkIndex = 1; chunkIndex < totalChunks; chunkIndex++) {\n if (signal?.aborted) throw new AbortError('Aborted')\n\n const chunk = await getChunk(auth, statementId, chunkIndex, signal)\n\n // Additional chunks should also be data_array (INLINE)\n if (chunk.external_links)\n throw new DatabricksSqlError(\n 'fetchRow only supports INLINE results. Chunk contains external_links.',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n\n if (chunk.data_array) {\n for (const row of chunk.data_array) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Apply the same mapping for each chunked row.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n }\n }\n}\n\nasync function consumeJsonArrayStream(\n stream: Readable,\n mapRow: (row: RowArray) => RowArray | RowObject,\n onEachRow: ((row: RowArray | RowObject) => void) | undefined,\n signal: AbortSignal | undefined,\n logger: FetchRowsOptions['logger'],\n logContext: Record<string, unknown>\n): Promise<void> {\n // Stream JSON_ARRAY as individual rows to avoid buffering whole payloads.\n const jsonStream = stream.pipe(parser()).pipe(streamArray())\n\n for await (const item of jsonStream) {\n if (signal?.aborted) {\n logger?.info?.('fetchRow abort detected while streaming JSON_ARRAY rows.', {\n ...logContext,\n aborted: signal.aborted,\n })\n stream.destroy(new AbortError('Aborted'))\n throw new AbortError('Aborted')\n }\n\n const row = item.value\n if (!Array.isArray(row)) {\n throw new DatabricksSqlError(\n 'Expected JSON_ARRAY rows to be arrays',\n 'INVALID_FORMAT'\n )\n }\n\n onEachRow?.(mapRow(row))\n }\n}\n","import { DatabricksSqlError } from './errors.js'\nimport type {\n ColumnInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementManifest,\n} from './types.js'\n\ntype RowMapper = (row: RowArray) => RowArray | RowObject\n\ntype TypeDescriptor = {\n typeName: string\n typeText: string\n precision?: number\n scale?: number\n fields?: StructField[]\n elementType?: TypeDescriptor\n keyType?: TypeDescriptor\n valueType?: TypeDescriptor\n}\n\ntype StructField = {\n name: string\n type: TypeDescriptor\n}\n\n// Type buckets used for value conversion decisions.\nconst INTEGER_TYPES = new Set(['TINYINT', 'SMALLINT', 'INT'])\nconst BIGINT_TYPES = new Set(['BIGINT', 'LONG'])\nconst FLOAT_TYPES = new Set(['FLOAT', 'DOUBLE'])\nconst BOOLEAN_TYPES = new Set(['BOOLEAN'])\nconst STRING_TYPES = new Set([\n 'STRING',\n 'DATE',\n 'TIMESTAMP',\n 'TIMESTAMP_NTZ',\n 'TIMESTAMP_LTZ',\n 'TIME',\n])\n\n/**\n * Create a row mapper that converts JSON_ARRAY rows into JSON_OBJECTs.\n * Datetime-like fields are preserved as strings to avoid locale/zone surprises.\n * DECIMAL values are converted to numbers to match the Databricks SDK behavior.\n */\nexport function createRowMapper(\n manifest: StatementManifest,\n format: FetchRowsOptions['format']\n): RowMapper {\n if (format !== 'JSON_OBJECT')\n return (row) => row\n\n // Precompute per-column converters for fast row mapping.\n const columnConverters = manifest.schema.columns.map((column: ColumnInfo) => ({\n name: column.name,\n convert: createColumnConverter(column),\n }))\n\n return (row) => {\n const mapped: RowObject = {}\n for (let index = 0; index < columnConverters.length; index++) {\n const converter = columnConverters[index]\n if (!converter)\n continue\n\n const { name, convert } = converter\n if (name)\n mapped[name] = convert(row[index])\n }\n return mapped\n }\n}\n\nfunction createColumnConverter(column: ColumnInfo): (value: unknown) => unknown {\n const descriptor = parseColumnType(column)\n return (value) => convertValue(descriptor, value)\n}\n\nfunction parseColumnType(column: ColumnInfo): TypeDescriptor {\n if (column.type_name === 'STRUCT' || column.type_name === 'ARRAY' || column.type_name === 'MAP')\n return parseTypeDescriptor(column.type_text)\n\n if (column.type_name === 'DECIMAL')\n // Prefer precision/scale provided by the API when available.\n return createDecimalDescriptor({\n typeName: column.type_name,\n typeText: column.type_text,\n }, column.type_precision, column.type_scale)\n\n return {\n typeName: column.type_name,\n typeText: column.type_text,\n }\n}\n\nfunction parseTypeDescriptor(typeText: string): TypeDescriptor {\n const trimmed = typeText.trim()\n const typeName = getTypeName(trimmed)\n\n if (typeName === 'STRUCT')\n // STRUCT fields are parsed recursively from type_text.\n return {\n typeName,\n typeText: trimmed,\n fields: parseStructFields(trimmed),\n }\n\n if (typeName === 'ARRAY') {\n const elementTypeText = parseSingleTypeArgument(trimmed)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (elementTypeText)\n descriptor.elementType = parseTypeDescriptor(elementTypeText)\n return descriptor\n }\n\n if (typeName === 'MAP') {\n const [keyTypeText, valueTypeText] = parseTypeArguments(trimmed, 2)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (keyTypeText)\n descriptor.keyType = parseTypeDescriptor(keyTypeText)\n if (valueTypeText)\n descriptor.valueType = parseTypeDescriptor(valueTypeText)\n return descriptor\n }\n\n if (typeName === 'DECIMAL') {\n // DECIMAL(precision, scale) needs explicit parsing for integer conversion.\n const { precision, scale } = parseDecimalInfo(trimmed)\n return createDecimalDescriptor({ typeName, typeText: trimmed }, precision, scale)\n }\n\n return {\n typeName,\n typeText: trimmed,\n }\n}\n\nfunction getTypeName(typeText: string): string {\n return typeText.match(/^[A-Z_]+/)?.[0] ?? typeText\n}\n\nfunction parseDecimalInfo(typeText: string): { precision?: number; scale?: number } {\n const match = typeText.match(/DECIMAL\\((\\d+),\\s*(\\d+)\\)/)\n if (!match)\n return {}\n\n return {\n precision: Number(match[1]),\n scale: Number(match[2]),\n }\n}\n\nfunction createDecimalDescriptor(\n base: Omit<TypeDescriptor, 'precision' | 'scale'>,\n precision?: number,\n scale?: number\n): TypeDescriptor {\n const descriptor: TypeDescriptor = { ...base }\n if (precision !== undefined)\n descriptor.precision = precision\n if (scale !== undefined)\n descriptor.scale = scale\n return descriptor\n}\n\nfunction parseStructFields(typeText: string): StructField[] {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n // Split by commas only at the top level of nested type definitions.\n const parts = splitTopLevel(inner)\n const fields: StructField[] = []\n\n for (const part of parts) {\n const separatorIndex = part.indexOf(':')\n if (separatorIndex === -1)\n continue\n\n const name = part.slice(0, separatorIndex).trim()\n let fieldTypeText = part.slice(separatorIndex + 1).trim()\n fieldTypeText = stripNotNull(fieldTypeText)\n\n if (!name)\n continue\n\n fields.push({\n name,\n type: parseTypeDescriptor(fieldTypeText),\n })\n }\n\n return fields\n}\n\nfunction parseSingleTypeArgument(typeText: string): string | null {\n const [arg] = parseTypeArguments(typeText, 1)\n return arg ?? null\n}\n\nfunction parseTypeArguments(typeText: string, expectedCount: number): Array<string | undefined> {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n const parts = splitTopLevel(inner)\n if (parts.length < expectedCount)\n return parts\n\n return parts.slice(0, expectedCount).map((part) => stripNotNull(part.trim()))\n}\n\nfunction splitTopLevel(value: string): string[] {\n const result: string[] = []\n let current = ''\n let angleDepth = 0\n let parenDepth = 0\n\n for (const char of value) {\n if (char === '<') angleDepth++\n if (char === '>') angleDepth--\n if (char === '(') parenDepth++\n if (char === ')') parenDepth--\n\n if (char === ',' && angleDepth === 0 && parenDepth === 0) {\n result.push(current.trim())\n current = ''\n continue\n }\n\n current += char\n }\n\n if (current.trim().length > 0)\n result.push(current.trim())\n\n return result\n}\n\nfunction stripNotNull(typeText: string): string {\n let trimmed = typeText.trim()\n while (trimmed.endsWith('NOT NULL'))\n trimmed = trimmed.slice(0, -'NOT NULL'.length).trim()\n return trimmed\n}\n\nfunction convertValue(descriptor: TypeDescriptor, value: unknown): unknown {\n if (value === null || value === undefined)\n return value\n\n if (descriptor.typeName === 'STRUCT' && descriptor.fields)\n // STRUCT values are JSON strings in JSON_ARRAY format.\n return convertStructValue(descriptor.fields, value)\n\n if (descriptor.typeName === 'ARRAY' && descriptor.elementType)\n return convertArrayValue(descriptor.elementType, value)\n\n if (descriptor.typeName === 'MAP' && descriptor.keyType && descriptor.valueType)\n return convertMapValue(descriptor.keyType, descriptor.valueType, value)\n\n if (descriptor.typeName === 'DECIMAL')\n return convertNumber(value)\n\n if (INTEGER_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BIGINT_TYPES.has(descriptor.typeName))\n return convertInteger(value)\n\n if (FLOAT_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BOOLEAN_TYPES.has(descriptor.typeName))\n return convertBoolean(value)\n\n if (STRING_TYPES.has(descriptor.typeName))\n return value\n\n return value\n}\n\nfunction convertStructValue(fields: StructField[], value: unknown): unknown {\n const raw = parseStructValue(value)\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return value\n\n // Apply nested field conversions based on the parsed STRUCT schema.\n const mapped: RowObject = {}\n for (const field of fields)\n mapped[field.name] = convertValue(field.type, (raw as RowObject)[field.name])\n\n return mapped\n}\n\nfunction convertArrayValue(elementType: TypeDescriptor, value: unknown): unknown {\n const raw = parseJsonValue(value)\n if (!Array.isArray(raw))\n return value\n\n return raw.map((entry) => convertValue(elementType, entry))\n}\n\nfunction convertMapValue(\n keyType: TypeDescriptor,\n valueType: TypeDescriptor,\n value: unknown\n): unknown {\n const raw = parseJsonValue(value)\n if (!raw || typeof raw !== 'object')\n return value\n\n if (Array.isArray(raw)) {\n const mapped: RowObject = {}\n for (const entry of raw) {\n if (!Array.isArray(entry) || entry.length < 2)\n continue\n const convertedKey = convertValue(keyType, entry[0])\n mapped[String(convertedKey)] = convertValue(valueType, entry[1])\n }\n return mapped\n }\n\n const mapped: RowObject = {}\n for (const [key, entryValue] of Object.entries(raw)) {\n const convertedKey = convertValue(keyType, key)\n mapped[String(convertedKey)] = convertValue(valueType, entryValue)\n }\n\n return mapped\n}\n\nfunction parseStructValue(value: unknown): RowObject | null {\n const parsed = parseJsonValue(value)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed as RowObject\n\n return parsed as RowObject | null\n}\n\nfunction parseJsonValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value)\n } catch {\n throw new DatabricksSqlError('Failed to parse JSON value', 'INVALID_JSON')\n }\n }\n\n return value\n}\n\nfunction convertNumber(value: unknown): unknown {\n if (typeof value === 'number')\n return value\n\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? value : parsed\n }\n\n return value\n}\n\nfunction convertInteger(value: unknown): unknown {\n if (typeof value === 'bigint')\n return value\n\n if (typeof value === 'number') {\n if (Number.isInteger(value))\n return BigInt(value)\n return value\n }\n\n if (typeof value === 'string') {\n try {\n // Preserve integer semantics for BIGINT/DECIMAL(scale=0) by returning bigint.\n return BigInt(value)\n } catch {\n return value\n }\n }\n\n return value\n}\n\nfunction convertBoolean(value: unknown): unknown {\n if (typeof value === 'boolean')\n return value\n\n if (typeof value === 'string') {\n if (value === 'true') return true\n if (value === 'false') return false\n }\n\n return value\n}\n","import type { MergeFormat } from '@bitofsky/merge-streams'\nimport type {\n AuthInfo,\n ExternalLinkInfo,\n FetchStreamOptions,\n StatementManifest,\n StatementResult,\n} from '../types.js'\n\nimport { PassThrough, Readable } from 'node:stream'\n\nimport { mergeStreamsFromUrls } from '@bitofsky/merge-streams'\n\nimport { getChunk } from '../databricks-api.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { pipeUrlToOutput, validateSucceededResult } from '../util.js'\n\n/**\n * Create a readable stream from statement result.\n * Merges all external link chunks into a single binary stream,\n * preserving the original format (JSON_ARRAY, CSV, ARROW_STREAM).\n */\nexport function fetchStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchStreamOptions = {}\n): Readable {\n const { signal, forceMerge, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const format = manifest.format as MergeFormat\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n\n if (statementResult.result?.data_array) {\n logger?.error?.(\n `fetchStream only supports EXTERNAL_LINKS results for statement ${statementId}.`,\n { ...baseLog, hasDataArray: true }\n )\n throw new DatabricksSqlError(\n 'fetchStream only supports EXTERNAL_LINKS results',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchStream creating stream for statement ${statementId}.`, {\n ...baseLog,\n hasExternalLinks: Boolean(statementResult.result?.external_links?.length),\n })\n\n // Create PassThrough as output (readable by consumer)\n const output = new PassThrough()\n\n // Handle AbortSignal\n if (signal) {\n const onAbort = () => {\n logger?.info?.(`fetchStream abort signal received while streaming statement ${statementId}.`, baseLog)\n output.destroy(new AbortError('Stream aborted'))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n output.once('close', () => signal.removeEventListener('abort', onAbort))\n }\n\n // Prevent AbortError from becoming an uncaught exception when no error handler is attached.\n output.on('error', (err) => {\n if (err instanceof AbortError)\n return\n if (output.listenerCount('error') === 1)\n throw err\n })\n\n // Start async merge process\n // Errors are forwarded to the stream consumer via destroy.\n mergeChunksToStream(statementResult, auth, manifest, format, output, signal, forceMerge, logger)\n .catch((err) => {\n logger?.error?.(`fetchStream error while streaming statement ${statementId}.`, {\n ...baseLog,\n error: err,\n })\n output.destroy(err as Error)\n })\n\n return output\n}\n\n/**\n * Collect all external link URLs and merge them into output stream\n */\nasync function mergeChunksToStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n format: MergeFormat,\n output: PassThrough,\n signal?: AbortSignal,\n forceMerge?: boolean,\n logger?: FetchStreamOptions['logger']\n): Promise<void> {\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n logger?.info?.(`fetchStream collecting external links for statement ${statementId}.`, baseLog)\n const urls = await collectExternalUrls(statementResult, auth, manifest, signal)\n\n // No external links - close the stream\n if (urls.length === 0) {\n logger?.info?.(`fetchStream no external links found for statement ${statementId}.`, baseLog)\n return void output.end()\n }\n\n // Single URL - pipe directly to output unless forcing merge\n if (urls.length === 1 && !forceMerge) {\n logger?.info?.(`fetchStream piping single external link for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n // Avoid merge-streams overhead for a single URL unless forced.\n return pipeUrlToOutput(urls[0]!, output, signal)\n }\n\n // Merge all URLs using merge-streams\n logger?.info?.(`fetchStream merging ${urls.length} external links for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n return mergeStreamsFromUrls(format, signal ? { urls, output, signal } : { urls, output })\n}\n\nasync function collectExternalUrls(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n signal?: AbortSignal\n): Promise<string[]> {\n const chunkUrls = new Map<number, string[]>()\n\n addChunkLinks(chunkUrls, statementResult.result?.external_links)\n\n if (!manifest.total_chunk_count)\n return flattenChunkUrls(chunkUrls)\n\n for (let i = 0; i < manifest.total_chunk_count; i++) {\n if (chunkUrls.has(i))\n continue\n if (signal?.aborted)\n throw new AbortError('Aborted while collecting URLs')\n\n // Chunk metadata contains external link URLs when results are chunked.\n const chunkData = await getChunk(auth, statementResult.statement_id, i, signal)\n addChunkLinks(chunkUrls, chunkData.external_links)\n }\n\n return flattenChunkUrls(chunkUrls)\n}\n\nfunction addChunkLinks(\n chunkUrls: Map<number, string[]>,\n externalLinks?: ExternalLinkInfo[]\n): void {\n if (!externalLinks)\n return\n\n for (const link of externalLinks) {\n if (!isNonEmptyString(link.external_link))\n continue\n\n const existing = chunkUrls.get(link.chunk_index)\n if (existing) {\n existing.push(link.external_link)\n } else {\n chunkUrls.set(link.chunk_index, [link.external_link])\n }\n }\n}\n\nfunction flattenChunkUrls(chunkUrls: Map<number, string[]>): string[] {\n if (chunkUrls.size === 0)\n return []\n\n const sorted = [...chunkUrls.entries()].sort(([a], [b]) => a - b)\n const urls: string[] = []\n for (const [, links] of sorted) {\n urls.push(...links)\n }\n return urls\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n","import type {\n AuthInfo,\n FetchAllOptions,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { fetchRow } from './fetchRow.js'\n\n/**\n * Fetch all rows from statement result as an array.\n * Only supports INLINE results or JSON_ARRAY external links.\n */\nexport async function fetchAll(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchAllOptions = {}\n): Promise<Array<RowArray | RowObject>> {\n const rows: Array<RowArray | RowObject> = []\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const logContext = { statementId, manifest, requestedFormat: options.format }\n const fetchOptions: FetchRowsOptions = {\n // Collect rows as they are streamed in.\n onEachRow: (row) => {\n rows.push(row)\n },\n }\n const { logger } = options\n\n logger?.info?.(`fetchAll fetching all rows for statement ${statementId}.`, logContext)\n\n if (options.signal)\n fetchOptions.signal = options.signal\n\n if (options.format)\n fetchOptions.format = options.format\n\n if (options.logger)\n fetchOptions.logger = options.logger\n\n await fetchRow(statementResult, auth, fetchOptions)\n logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {\n ...logContext,\n rowCount: rows.length,\n resolvedFormat: options.format ?? manifest?.format,\n })\n return rows\n}\n","import type {\n AuthInfo,\n MergeExternalLinksOptions,\n StatementResult,\n} from '../types.js'\n\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Merge external links from StatementResult into a single stream,\n * upload it via the provided callback, and return updated StatementResult.\n *\n * If the result is not external links (inline data or empty), returns the original as-is.\n */\nexport async function mergeExternalLinks(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: MergeExternalLinksOptions\n): Promise<StatementResult> {\n const { signal, mergeStreamToExternalLink, forceMerge, logger } = options\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const externalLinks = statementResult.result?.external_links\n const totalChunks = manifest?.total_chunk_count ?? 0\n const logContext = { statementId, manifest, totalChunks, forceMerge }\n\n // If not external links, return original as-is\n if (!externalLinks) {\n logger?.info?.(`mergeExternalLinks no external links to merge for statement ${statementId}.`, logContext)\n return statementResult\n }\n\n if (!forceMerge) {\n const isSingleChunk = totalChunks <= 1\n\n // Skip merging when a single external link already exists unless forced.\n if (isSingleChunk) {\n logger?.info?.(`mergeExternalLinks skipping merge for single external link in statement ${statementId}.`, {\n ...logContext,\n totalChunks,\n })\n return statementResult\n }\n }\n\n // Get merged stream via fetchStream\n logger?.info?.(`mergeExternalLinks merging external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...forceMerge !== undefined ? { forceMerge } : {},\n ...logger ? { logger } : {},\n })\n\n // Upload via callback\n logger?.info?.(`mergeExternalLinks uploading merged external link for statement ${statementId}.`, logContext)\n const uploadResult = await mergeStreamToExternalLink(stream)\n logger?.info?.(`mergeExternalLinks uploaded merged external link for statement ${statementId}.`, {\n ...logContext,\n byteCount: uploadResult.byte_count,\n expiration: uploadResult.expiration,\n })\n\n // Build updated StatementResult\n // Manifest must exist for external links; validate before constructing new result.\n const validatedManifest = validateSucceededResult(statementResult)\n const totalRowCount = validatedManifest.total_row_count ?? 0\n\n return {\n statement_id: statementResult.statement_id,\n status: statementResult.status,\n manifest: {\n ...validatedManifest,\n total_chunk_count: 1,\n total_byte_count: uploadResult.byte_count,\n chunks: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n },\n ],\n },\n result: {\n external_links: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n external_link: uploadResult.externalLink,\n expiration: uploadResult.expiration,\n },\n ],\n },\n }\n}\n"],"mappings":"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","names":["errorBody","mapped"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/util.ts","../src/http.ts","../src/databricks-api.ts","../src/api/executeStatement.ts","../src/api/fetchRow.ts","../src/createRowMapper.ts","../src/api/fetchStream.ts","../src/api/fetchAll.ts","../src/api/mergeExternalLinks.ts"],"sourcesContent":["/** Base error for Databricks SQL operations */\nexport class DatabricksSqlError extends Error {\n readonly code: string\n readonly statementId: string | undefined\n\n constructor(message: string, code?: string, statementId?: string) {\n super(message)\n this.name = 'DatabricksSqlError'\n this.code = code ?? 'UNKNOWN_ERROR'\n this.statementId = statementId\n Error.captureStackTrace?.(this, DatabricksSqlError)\n }\n}\n\n/** Error when statement is cancelled */\nexport class StatementCancelledError extends DatabricksSqlError {\n constructor(statementId: string) {\n super(`Statement ${statementId} was cancelled`, 'CANCELLED', statementId)\n this.name = 'StatementCancelledError'\n }\n}\n\n/** Error when operation is aborted via AbortSignal */\nexport class AbortError extends DatabricksSqlError {\n constructor(message: string = 'Operation was aborted') {\n super(message, 'ABORTED')\n this.name = 'AbortError'\n }\n}\n\n/** HTTP error from API calls */\nexport class HttpError extends DatabricksSqlError {\n readonly status: number\n readonly statusText: string\n\n constructor(status: number, statusText: string, message?: string) {\n super(message ?? `HTTP ${status}: ${statusText}`, `HTTP_${status}`)\n this.name = 'HttpError'\n this.status = status\n this.statusText = statusText\n }\n}\n\n/** Authentication error (401) */\nexport class AuthenticationError extends HttpError {\n constructor() {\n super(401, 'Unauthorized', 'Authentication failed. Check your token.')\n this.name = 'AuthenticationError'\n }\n}\n\n/** Rate limit error (429) */\nexport class RateLimitError extends HttpError {\n readonly retryAfter: number | undefined\n\n constructor(retryAfter?: number) {\n super(429, 'Too Many Requests', 'Rate limit exceeded')\n this.name = 'RateLimitError'\n this.retryAfter = retryAfter\n }\n}\n","import { Readable } from 'node:stream'\nimport { pipeline } from 'node:stream/promises'\nimport type { ReadableStream as WebReadableStream } from 'node:stream/web'\nimport type { StatementResult, StatementManifest } from './types.js'\nimport { AbortError, DatabricksSqlError } from './errors.js'\n\n/**\n * Extract warehouse_id from httpPath\n * @example \"/sql/1.0/warehouses/abc123def456\" -> \"abc123def456\"\n */\nexport function extractWarehouseId(httpPath: string): string {\n const match = httpPath.match(/\\/sql\\/\\d+\\.\\d+\\/warehouses\\/([a-zA-Z0-9]+)/)\n if (!match?.[1])\n throw new Error(`Cannot extract warehouse_id from httpPath: ${httpPath}`)\n return match[1]\n}\n\n/**\n * Throw AbortError if signal is aborted\n */\nexport function throwIfAborted(signal: AbortSignal | undefined, context: string): void {\n if (signal?.aborted)\n throw new AbortError(`[${context}] Aborted`)\n}\n\n/**\n * Delay for specified milliseconds with AbortSignal support\n */\nexport async function delay(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted)\n return reject(new AbortError('Aborted before delay'))\n\n let settled = false\n\n const onAbort = () => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n reject(new AbortError('Aborted during delay'))\n }\n\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\n/**\n * Build full URL from host and path\n */\nexport function buildUrl(host: string, path: string): string {\n const base = host.startsWith('https://') ? host : `https://${host}`\n return new URL(path, base).href\n}\n\n/**\n * Validate statement result is in SUCCEEDED state with manifest.\n * Returns the manifest for convenience.\n * @throws {DatabricksSqlError} If state is not SUCCEEDED or manifest is missing\n */\nexport function validateSucceededResult(\n statementResult: StatementResult\n): StatementManifest {\n if (statementResult.status.state !== 'SUCCEEDED')\n throw new DatabricksSqlError(\n `Cannot fetch from non-succeeded statement: ${statementResult.status.state}`,\n 'INVALID_STATE',\n statementResult.statement_id\n )\n\n if (!statementResult.manifest)\n throw new DatabricksSqlError(\n 'Statement result has no manifest',\n 'MISSING_MANIFEST',\n statementResult.statement_id\n )\n\n return statementResult.manifest\n}\n\nfunction isWebReadableStream(body: unknown): body is WebReadableStream {\n return typeof (body as WebReadableStream).getReader === 'function'\n}\n\nexport async function pipeUrlToOutput(\n url: string,\n output: NodeJS.WritableStream,\n signal?: AbortSignal\n): Promise<void> {\n // Uses Node 20+ global fetch with Web streams.\n if (signal?.aborted)\n throw new AbortError('Aborted while streaming')\n\n const response = await fetch(url, signal ? { signal } : undefined)\n if (!response.ok) {\n throw new Error(\n `Failed to fetch external link: ${response.status} ${response.statusText}`\n )\n }\n\n if (!response.body)\n return void output.end()\n\n const body = response.body\n const input = isWebReadableStream(body)\n ? Readable.fromWeb(body)\n : (body as NodeJS.ReadableStream)\n\n await pipeline(input, output)\n}\n","import type { AuthInfo } from './types.js'\nimport {\n HttpError,\n AuthenticationError,\n RateLimitError,\n AbortError,\n} from './errors.js'\nimport { buildUrl, delay } from './util.js'\n\nconst MAX_RETRIES = 3\nconst INITIAL_RETRY_DELAY_MS = 1000\n\ntype HttpMethod = 'GET' | 'POST' | 'DELETE'\n\ntype HttpRequestOptions = {\n method: HttpMethod\n path: string\n body?: unknown\n signal?: AbortSignal\n}\n\n/**\n * HTTP request wrapper with retry and error handling\n */\nexport async function httpRequest<T>(\n auth: AuthInfo,\n options: HttpRequestOptions\n): Promise<T> {\n const { method, path, body, signal } = options\n const url = buildUrl(auth.host, path)\n\n let lastError: Error | undefined\n let retryDelay = INITIAL_RETRY_DELAY_MS\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n if (signal?.aborted)\n throw new AbortError()\n\n try {\n // Build a minimal fetch init, skipping undefined values.\n const fetchInit = Object.fromEntries(\n Object.entries({\n method,\n headers: {\n Authorization: `Bearer ${auth.token}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n }).filter(([, v]) => v !== undefined)\n ) as RequestInit\n\n const response = await fetch(url, fetchInit)\n\n // Success\n if (response.ok)\n return (await response.json()) as T\n\n // Authentication error (no retry)\n if (response.status === 401)\n throw new AuthenticationError()\n\n // Rate limit\n if (response.status === 429) {\n const retryAfterHeader = response.headers.get('Retry-After')\n const retryAfter = retryAfterHeader\n ? parseInt(retryAfterHeader, 10)\n : undefined\n const error = new RateLimitError(\n isNaN(retryAfter as number) ? undefined : retryAfter\n )\n\n if (error.retryAfter && attempt < MAX_RETRIES) {\n await delay(error.retryAfter * 1000, signal)\n continue\n }\n\n throw error\n }\n\n // Server error (can retry)\n if (response.status >= 500) {\n const errorBody = await response.text().catch(() => '')\n lastError = new HttpError(response.status, response.statusText, errorBody)\n\n if (attempt < MAX_RETRIES) {\n // Exponential backoff for transient server errors.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n // Other client errors\n const errorBody = await response.text().catch(() => '')\n\n throw new HttpError(response.status, response.statusText, errorBody)\n\n } catch (err) {\n // Re-throw known errors\n if (\n err instanceof AbortError ||\n err instanceof AuthenticationError ||\n err instanceof HttpError\n )\n throw err\n\n // Network error\n if (err instanceof TypeError && err.message.includes('fetch')) {\n lastError = err\n if (attempt < MAX_RETRIES) {\n // Network errors are retried with backoff.\n await delay(retryDelay, signal)\n retryDelay *= 2\n continue\n }\n }\n\n throw err\n }\n }\n\n throw lastError ?? new Error('Request failed after retries')\n}\n","import type {\n AuthInfo,\n ExecuteStatementRequest,\n StatementResult,\n GetChunkResponse,\n QueryInfo,\n} from './types.js'\nimport { httpRequest } from './http.js'\n\n// Base path for Databricks SQL Statement Execution API.\nconst BASE_PATH = '/api/2.0/sql/statements'\n// Base path for Query History API.\nconst HISTORY_BASE_PATH = '/api/2.0/sql/history/queries'\n\n/**\n * Execute SQL statement\n * POST /api/2.0/sql/statements\n */\nexport async function postStatement(\n auth: AuthInfo,\n request: ExecuteStatementRequest,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'POST',\n path: BASE_PATH,\n body: request,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get statement status and result\n * GET /api/2.0/sql/statements/{statement_id}\n */\nexport async function getStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<StatementResult> {\n return httpRequest<StatementResult>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Cancel statement execution\n * POST /api/2.0/sql/statements/{statement_id}/cancel\n */\nexport async function cancelStatement(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<void> {\n await httpRequest<unknown>(auth, {\n method: 'POST',\n path: `${BASE_PATH}/${statementId}/cancel`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get result chunk by index\n * GET /api/2.0/sql/statements/{statement_id}/result/chunks/{chunk_index}\n */\nexport async function getChunk(\n auth: AuthInfo,\n statementId: string,\n chunkIndex: number,\n signal?: AbortSignal\n): Promise<GetChunkResponse> {\n return httpRequest<GetChunkResponse>(auth, {\n method: 'GET',\n path: `${BASE_PATH}/${statementId}/result/chunks/${chunkIndex}`,\n ...(signal ? { signal } : {}),\n })\n}\n\n/**\n * Get query metrics from Query History API\n * GET /api/2.0/sql/history/queries/{query_id}?include_metrics=true\n */\nexport async function getQueryMetrics(\n auth: AuthInfo,\n queryId: string,\n signal?: AbortSignal\n): Promise<QueryInfo> {\n return httpRequest<QueryInfo>(auth, {\n method: 'GET',\n path: `${HISTORY_BASE_PATH}/${queryId}?include_metrics=true`,\n ...(signal ? { signal } : {}),\n })\n}\n","import type {\n AuthInfo,\n ExecuteStatementOptions,\n ExecuteStatementRequest,\n StatementResult,\n StatementState,\n QueryMetrics,\n} from '../types.js'\nimport { postStatement, getStatement, cancelStatement, getQueryMetrics } from '../databricks-api.js'\nimport { extractWarehouseId, throwIfAborted, delay } from '../util.js'\nimport {\n DatabricksSqlError,\n StatementCancelledError,\n AbortError,\n} from '../errors.js'\n\nconst TERMINAL_STATES = new Set<StatementState>([\n 'SUCCEEDED',\n 'FAILED',\n 'CANCELED',\n 'CLOSED',\n])\nconst POLL_INTERVAL_MS = 5000\n\nasync function fetchMetrics(\n auth: AuthInfo,\n statementId: string,\n signal?: AbortSignal\n): Promise<QueryMetrics | undefined> {\n const queryInfo = await getQueryMetrics(auth, statementId, signal)\n return queryInfo.metrics\n}\n\n/**\n * Execute SQL statement and poll until completion\n */\nexport async function executeStatement(\n query: string,\n auth: AuthInfo,\n options: ExecuteStatementOptions = {}\n): Promise<StatementResult> {\n const warehouseId = options.warehouse_id ?? extractWarehouseId(auth.httpPath)\n const { signal, onProgress, enableMetrics, logger } = options\n const waitTimeout = options.wait_timeout ?? (onProgress ? '0s' : '50s')\n let cancelIssued = false\n\n // Check if already aborted\n throwIfAborted(signal, 'executeStatement')\n\n // Helper to call onProgress with optional metrics\n const emitProgress = onProgress\n ? async () => result ? onProgress(\n result,\n enableMetrics ? await fetchMetrics(auth, result.statement_id, signal).catch(e => {\n logger?.error?.(`executeStatement Failed to fetch query metrics for statement ${result?.statement_id}: ${String(e)}`, { statementId: result?.statement_id })\n return undefined\n }) : undefined\n ) : undefined\n : undefined\n\n // 1. Build request (filter out undefined values)\n const request = Object.fromEntries(\n Object.entries({\n warehouse_id: warehouseId,\n statement: query,\n byte_limit: options.byte_limit,\n disposition: options.disposition,\n format: options.format,\n on_wait_timeout: options.on_wait_timeout ?? 'CONTINUE',\n wait_timeout: waitTimeout,\n row_limit: options.row_limit,\n catalog: options.catalog,\n schema: options.schema,\n parameters: options.parameters,\n }).filter(([, v]) => v !== undefined)\n ) as ExecuteStatementRequest\n\n logger?.info?.(`executeStatement Executing statement on warehouse ${warehouseId}...`)\n\n // 2. Submit statement execution request\n let result = await postStatement(auth, request, signal)\n const cancelStatementSafely = async () => {\n if (cancelIssued) return\n logger?.info?.('executeStatement Abort signal received during executeStatement.')\n cancelIssued = true\n await cancelStatement(auth, result.statement_id).catch((err) => {\n logger?.error?.('executeStatement Failed to cancel statement after abort.', err)\n })\n }\n\n if (signal?.aborted) {\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n\n const onAbort = () => cancelStatementSafely().catch(() => { })\n\n try {\n signal?.addEventListener('abort', onAbort, { once: true })\n\n // 3. Poll until terminal state\n while (!TERMINAL_STATES.has(result.status.state)) {\n logger?.info?.(`executeStatement Statement ${result.statement_id} in state ${result.status.state}; polling for status...`)\n await delay(POLL_INTERVAL_MS, signal)\n result = await getStatement(auth, result.statement_id, signal)\n await emitProgress?.()\n }\n } catch (err) {\n if (err instanceof AbortError || signal?.aborted) {\n logger?.info?.('executeStatement Abort detected in executeStatement polling loop.')\n await cancelStatementSafely()\n throw new AbortError('Aborted during polling')\n }\n logger?.error?.(`executeStatement Error during executeStatement polling: ${String(err)}`)\n throw err\n } finally {\n logger?.info?.(`executeStatement Statement ${result.statement_id} reached final state: ${result.status.state}`)\n signal?.removeEventListener('abort', onAbort)\n }\n\n // 4. Final progress callback\n await emitProgress?.()\n\n // 5. Handle terminal states\n if (result.status.state === 'SUCCEEDED')\n return result\n\n if (result.status.state === 'CANCELED')\n throw new StatementCancelledError(result.statement_id)\n\n // FAILED or CLOSED\n throw new DatabricksSqlError(\n result.status.error?.message ?? 'Statement execution failed',\n result.status.error?.error_code,\n result.statement_id\n )\n}\n","import type { Readable } from 'node:stream'\nimport type {\n AuthInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { parser } from 'stream-json'\nimport { streamArray } from 'stream-json/streamers/StreamArray'\n\nimport { getChunk } from '../databricks-api.js'\nimport { createRowMapper } from '../createRowMapper.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Process each row from statement result with a callback.\n * Supports INLINE results and JSON_ARRAY external links.\n */\nexport async function fetchRow(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchRowsOptions = {}\n): Promise<void> {\n const { signal, onEachRow, format, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const statementId = statementResult.statement_id\n const logContext = { statementId, manifest, requestedFormat: format }\n // Map JSON_ARRAY rows to JSON_OBJECT when requested.\n const mapRow = createRowMapper(manifest, format, {\n ...options.encodeBigInt ? { encodeBigInt: options.encodeBigInt } : {},\n ...options.encodeTimestamp ? { encodeTimestamp: options.encodeTimestamp } : {},\n })\n\n logger?.info?.(`fetchRow fetching rows for statement ${statementId}.`, {\n ...logContext,\n resultType: statementResult.result?.external_links ? 'EXTERNAL_LINKS' : 'INLINE',\n })\n\n if (statementResult.result?.external_links) {\n if (manifest.format !== 'JSON_ARRAY') {\n logger?.error?.(`fetchRow only supports JSON_ARRAY for external_links; got ${manifest.format}.`, logContext)\n throw new DatabricksSqlError(\n `fetchRow only supports JSON_ARRAY for external_links. Received: ${manifest.format}`,\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchRow streaming external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...logger ? { logger } : {},\n })\n await consumeJsonArrayStream(stream, mapRow, onEachRow, signal, logger, logContext)\n return\n }\n\n const totalChunks = manifest.total_chunk_count\n\n // Process first chunk (inline data_array)\n const dataArray = statementResult.result?.data_array\n if (dataArray) {\n logger?.info?.(`fetchRow processing inline rows for statement ${statementId}.`, {\n ...logContext,\n inlineRows: dataArray.length,\n })\n for (const row of dataArray) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Convert row to requested shape before callback.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n\n // Process additional chunks if any\n if (totalChunks > 1) {\n logger?.info?.(`fetchRow processing ${totalChunks} chunks for statement ${statementId}.`, logContext)\n for (let chunkIndex = 1; chunkIndex < totalChunks; chunkIndex++) {\n if (signal?.aborted) throw new AbortError('Aborted')\n\n const chunk = await getChunk(auth, statementId, chunkIndex, signal)\n\n // Additional chunks should also be data_array (INLINE)\n if (chunk.external_links)\n throw new DatabricksSqlError(\n 'fetchRow only supports INLINE results. Chunk contains external_links.',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n\n if (chunk.data_array) {\n for (const row of chunk.data_array) {\n if (signal?.aborted) throw new AbortError('Aborted')\n // Apply the same mapping for each chunked row.\n onEachRow?.(mapRow(row as RowArray))\n }\n }\n }\n }\n}\n\nasync function consumeJsonArrayStream(\n stream: Readable,\n mapRow: (row: RowArray) => RowArray | RowObject,\n onEachRow: ((row: RowArray | RowObject) => void) | undefined,\n signal: AbortSignal | undefined,\n logger: FetchRowsOptions['logger'],\n logContext: Record<string, unknown>\n): Promise<void> {\n // Stream JSON_ARRAY as individual rows to avoid buffering whole payloads.\n const jsonStream = stream.pipe(parser()).pipe(streamArray())\n\n for await (const item of jsonStream) {\n if (signal?.aborted) {\n logger?.info?.('fetchRow abort detected while streaming JSON_ARRAY rows.', {\n ...logContext,\n aborted: signal.aborted,\n })\n stream.destroy(new AbortError('Aborted'))\n throw new AbortError('Aborted')\n }\n\n const row = item.value\n if (!Array.isArray(row)) {\n throw new DatabricksSqlError(\n 'Expected JSON_ARRAY rows to be arrays',\n 'INVALID_FORMAT'\n )\n }\n\n onEachRow?.(mapRow(row))\n }\n}\n","import { DatabricksSqlError } from './errors.js'\nimport type {\n ColumnInfo,\n FetchRowsOptions,\n RowArray,\n RowObject,\n RowMapperOptions,\n StatementManifest,\n} from './types.js'\n\ntype RowMapper = (row: RowArray) => RowArray | RowObject\n\ntype TypeDescriptor = {\n typeName: string\n typeText: string\n precision?: number\n scale?: number\n fields?: StructField[]\n elementType?: TypeDescriptor\n keyType?: TypeDescriptor\n valueType?: TypeDescriptor\n}\n\ntype StructField = {\n name: string\n type: TypeDescriptor\n}\n\n// Type buckets used for value conversion decisions.\nconst INTEGER_TYPES = new Set(['TINYINT', 'SMALLINT', 'INT'])\nconst BIGINT_TYPES = new Set(['BIGINT', 'LONG'])\nconst FLOAT_TYPES = new Set(['FLOAT', 'DOUBLE'])\nconst BOOLEAN_TYPES = new Set(['BOOLEAN'])\nconst TIMESTAMP_TYPES = new Set(['TIMESTAMP', 'TIMESTAMP_NTZ', 'TIMESTAMP_LTZ'])\nconst STRING_TYPES = new Set([\n 'STRING',\n 'DATE',\n 'TIME',\n])\n\n/**\n * Create a row mapper that converts JSON_ARRAY rows into JSON_OBJECTs.\n * Datetime-like fields are preserved as strings to avoid locale/zone surprises.\n * DECIMAL values are converted to numbers to match the Databricks SDK behavior.\n */\nexport function createRowMapper(\n manifest: StatementManifest,\n format: FetchRowsOptions['format'],\n options: RowMapperOptions = {}\n): RowMapper {\n if (format !== 'JSON_OBJECT')\n return (row) => row\n\n // Precompute per-column converters for fast row mapping.\n const columnConverters = manifest.schema.columns.map((column: ColumnInfo) => ({\n name: column.name,\n convert: createColumnConverter(column, options),\n }))\n\n return (row) => {\n const mapped: RowObject = {}\n for (let index = 0; index < columnConverters.length; index++) {\n const converter = columnConverters[index]\n if (!converter)\n continue\n\n const { name, convert } = converter\n if (name)\n mapped[name] = convert(row[index])\n }\n return mapped\n }\n}\n\nfunction createColumnConverter(\n column: ColumnInfo,\n options: RowMapperOptions\n): (value: unknown) => unknown {\n const descriptor = parseColumnType(column)\n return (value) => convertValue(descriptor, value, options)\n}\n\nfunction parseColumnType(column: ColumnInfo): TypeDescriptor {\n if (column.type_name === 'STRUCT' || column.type_name === 'ARRAY' || column.type_name === 'MAP')\n return parseTypeDescriptor(column.type_text)\n\n if (column.type_name === 'DECIMAL')\n // Prefer precision/scale provided by the API when available.\n return createDecimalDescriptor({\n typeName: column.type_name,\n typeText: column.type_text,\n }, column.type_precision, column.type_scale)\n\n return {\n typeName: column.type_name,\n typeText: column.type_text,\n }\n}\n\nfunction parseTypeDescriptor(typeText: string): TypeDescriptor {\n const trimmed = typeText.trim()\n const typeName = getTypeName(trimmed)\n\n if (typeName === 'STRUCT')\n // STRUCT fields are parsed recursively from type_text.\n return {\n typeName,\n typeText: trimmed,\n fields: parseStructFields(trimmed),\n }\n\n if (typeName === 'ARRAY') {\n const elementTypeText = parseSingleTypeArgument(trimmed)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (elementTypeText)\n descriptor.elementType = parseTypeDescriptor(elementTypeText)\n return descriptor\n }\n\n if (typeName === 'MAP') {\n const [keyTypeText, valueTypeText] = parseTypeArguments(trimmed, 2)\n const descriptor: TypeDescriptor = {\n typeName,\n typeText: trimmed,\n }\n if (keyTypeText)\n descriptor.keyType = parseTypeDescriptor(keyTypeText)\n if (valueTypeText)\n descriptor.valueType = parseTypeDescriptor(valueTypeText)\n return descriptor\n }\n\n if (typeName === 'DECIMAL') {\n // DECIMAL(precision, scale) needs explicit parsing for integer conversion.\n const { precision, scale } = parseDecimalInfo(trimmed)\n return createDecimalDescriptor({ typeName, typeText: trimmed }, precision, scale)\n }\n\n return {\n typeName,\n typeText: trimmed,\n }\n}\n\nfunction getTypeName(typeText: string): string {\n return typeText.match(/^[A-Z_]+/)?.[0] ?? typeText\n}\n\nfunction parseDecimalInfo(typeText: string): { precision?: number; scale?: number } {\n const match = typeText.match(/DECIMAL\\((\\d+),\\s*(\\d+)\\)/)\n if (!match)\n return {}\n\n return {\n precision: Number(match[1]),\n scale: Number(match[2]),\n }\n}\n\nfunction createDecimalDescriptor(\n base: Omit<TypeDescriptor, 'precision' | 'scale'>,\n precision?: number,\n scale?: number\n): TypeDescriptor {\n const descriptor: TypeDescriptor = { ...base }\n if (precision !== undefined)\n descriptor.precision = precision\n if (scale !== undefined)\n descriptor.scale = scale\n return descriptor\n}\n\nfunction parseStructFields(typeText: string): StructField[] {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n // Split by commas only at the top level of nested type definitions.\n const parts = splitTopLevel(inner)\n const fields: StructField[] = []\n\n for (const part of parts) {\n const separatorIndex = part.indexOf(':')\n if (separatorIndex === -1)\n continue\n\n const name = part.slice(0, separatorIndex).trim()\n let fieldTypeText = part.slice(separatorIndex + 1).trim()\n fieldTypeText = stripNotNull(fieldTypeText)\n\n if (!name)\n continue\n\n fields.push({\n name,\n type: parseTypeDescriptor(fieldTypeText),\n })\n }\n\n return fields\n}\n\nfunction parseSingleTypeArgument(typeText: string): string | null {\n const [arg] = parseTypeArguments(typeText, 1)\n return arg ?? null\n}\n\nfunction parseTypeArguments(typeText: string, expectedCount: number): Array<string | undefined> {\n const start = typeText.indexOf('<')\n const end = typeText.lastIndexOf('>')\n if (start === -1 || end === -1 || end <= start)\n return []\n\n const inner = typeText.slice(start + 1, end)\n const parts = splitTopLevel(inner)\n if (parts.length < expectedCount)\n return parts\n\n return parts.slice(0, expectedCount).map((part) => stripNotNull(part.trim()))\n}\n\nfunction splitTopLevel(value: string): string[] {\n const result: string[] = []\n let current = ''\n let angleDepth = 0\n let parenDepth = 0\n\n for (const char of value) {\n if (char === '<') angleDepth++\n if (char === '>') angleDepth--\n if (char === '(') parenDepth++\n if (char === ')') parenDepth--\n\n if (char === ',' && angleDepth === 0 && parenDepth === 0) {\n result.push(current.trim())\n current = ''\n continue\n }\n\n current += char\n }\n\n if (current.trim().length > 0)\n result.push(current.trim())\n\n return result\n}\n\nfunction stripNotNull(typeText: string): string {\n let trimmed = typeText.trim()\n while (trimmed.endsWith('NOT NULL'))\n trimmed = trimmed.slice(0, -'NOT NULL'.length).trim()\n return trimmed\n}\n\nfunction convertValue(\n descriptor: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n if (value === null || value === undefined)\n return value\n\n if (descriptor.typeName === 'STRUCT' && descriptor.fields)\n // STRUCT values are JSON strings in JSON_ARRAY format.\n return convertStructValue(descriptor.fields, value, options)\n\n if (descriptor.typeName === 'ARRAY' && descriptor.elementType)\n return convertArrayValue(descriptor.elementType, value, options)\n\n if (descriptor.typeName === 'MAP' && descriptor.keyType && descriptor.valueType)\n return convertMapValue(descriptor.keyType, descriptor.valueType, value, options)\n\n if (descriptor.typeName === 'DECIMAL')\n return convertNumber(value)\n\n if (INTEGER_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BIGINT_TYPES.has(descriptor.typeName))\n return convertInteger(value, options.encodeBigInt)\n\n if (FLOAT_TYPES.has(descriptor.typeName))\n return convertNumber(value)\n\n if (BOOLEAN_TYPES.has(descriptor.typeName))\n return convertBoolean(value)\n\n if (TIMESTAMP_TYPES.has(descriptor.typeName))\n return convertTimestamp(value, options.encodeTimestamp)\n\n if (STRING_TYPES.has(descriptor.typeName))\n return value\n\n return value\n}\n\nfunction convertStructValue(\n fields: StructField[],\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseStructValue(value)\n if (!raw || typeof raw !== 'object' || Array.isArray(raw))\n return value\n\n // Apply nested field conversions based on the parsed STRUCT schema.\n const mapped: RowObject = {}\n for (const field of fields)\n mapped[field.name] = convertValue(field.type, (raw as RowObject)[field.name], options)\n\n return mapped\n}\n\nfunction convertArrayValue(\n elementType: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseJsonValue(value)\n if (!Array.isArray(raw))\n return value\n\n return raw.map((entry) => convertValue(elementType, entry, options))\n}\n\nfunction convertMapValue(\n keyType: TypeDescriptor,\n valueType: TypeDescriptor,\n value: unknown,\n options: RowMapperOptions\n): unknown {\n const raw = parseJsonValue(value)\n if (!raw || typeof raw !== 'object')\n return value\n\n if (Array.isArray(raw)) {\n const mapped: RowObject = {}\n for (const entry of raw) {\n if (!Array.isArray(entry) || entry.length < 2)\n continue\n const convertedKey = convertValue(keyType, entry[0], options)\n mapped[String(convertedKey)] = convertValue(valueType, entry[1], options)\n }\n return mapped\n }\n\n const mapped: RowObject = {}\n for (const [key, entryValue] of Object.entries(raw)) {\n const convertedKey = convertValue(keyType, key, options)\n mapped[String(convertedKey)] = convertValue(valueType, entryValue, options)\n }\n\n return mapped\n}\n\nfunction parseStructValue(value: unknown): RowObject | null {\n const parsed = parseJsonValue(value)\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed as RowObject\n\n return parsed as RowObject | null\n}\n\nfunction parseJsonValue(value: unknown): unknown {\n if (typeof value === 'string') {\n try {\n return JSON.parse(value)\n } catch {\n throw new DatabricksSqlError('Failed to parse JSON value', 'INVALID_JSON')\n }\n }\n\n return value\n}\n\nfunction convertNumber(value: unknown): unknown {\n if (typeof value === 'number')\n return value\n\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? value : parsed\n }\n\n return value\n}\n\nfunction convertInteger(value: unknown, encodeBigInt?: (value: bigint) => unknown): unknown {\n if (typeof value === 'bigint')\n return encodeBigInt ? encodeBigInt(value) : value\n\n if (typeof value === 'number') {\n if (Number.isInteger(value)) {\n const bigintValue = BigInt(value)\n return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue\n }\n return value\n }\n\n if (typeof value === 'string') {\n try {\n // Preserve integer semantics for BIGINT/DECIMAL(scale=0) by returning bigint.\n const bigintValue = BigInt(value)\n return encodeBigInt ? encodeBigInt(bigintValue) : bigintValue\n } catch {\n return value\n }\n }\n\n return value\n}\n\nfunction convertTimestamp(\n value: unknown,\n encodeTimestamp?: (value: string) => unknown\n): unknown {\n if (typeof value !== 'string')\n return value\n\n return encodeTimestamp ? encodeTimestamp(value) : value\n}\n\nfunction convertBoolean(value: unknown): unknown {\n if (typeof value === 'boolean')\n return value\n\n if (typeof value === 'string') {\n if (value === 'true') return true\n if (value === 'false') return false\n }\n\n return value\n}\n","import type { MergeFormat } from '@bitofsky/merge-streams'\nimport type {\n AuthInfo,\n ExternalLinkInfo,\n FetchStreamOptions,\n StatementManifest,\n StatementResult,\n} from '../types.js'\n\nimport { PassThrough, Readable } from 'node:stream'\n\nimport { mergeStreamsFromUrls } from '@bitofsky/merge-streams'\n\nimport { getChunk } from '../databricks-api.js'\nimport { AbortError, DatabricksSqlError } from '../errors.js'\nimport { pipeUrlToOutput, validateSucceededResult } from '../util.js'\n\n/**\n * Create a readable stream from statement result.\n * Merges all external link chunks into a single binary stream,\n * preserving the original format (JSON_ARRAY, CSV, ARROW_STREAM).\n */\nexport function fetchStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchStreamOptions = {}\n): Readable {\n const { signal, forceMerge, logger } = options\n const manifest = validateSucceededResult(statementResult)\n const format = manifest.format as MergeFormat\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n\n if (statementResult.result?.data_array) {\n logger?.error?.(\n `fetchStream only supports EXTERNAL_LINKS results for statement ${statementId}.`,\n { ...baseLog, hasDataArray: true }\n )\n throw new DatabricksSqlError(\n 'fetchStream only supports EXTERNAL_LINKS results',\n 'UNSUPPORTED_FORMAT',\n statementId\n )\n }\n\n logger?.info?.(`fetchStream creating stream for statement ${statementId}.`, {\n ...baseLog,\n hasExternalLinks: Boolean(statementResult.result?.external_links?.length),\n })\n\n // Create PassThrough as output (readable by consumer)\n const output = new PassThrough()\n\n // Handle AbortSignal\n if (signal) {\n const onAbort = () => {\n logger?.info?.(`fetchStream abort signal received while streaming statement ${statementId}.`, baseLog)\n output.destroy(new AbortError('Stream aborted'))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n output.once('close', () => signal.removeEventListener('abort', onAbort))\n }\n\n // Prevent AbortError from becoming an uncaught exception when no error handler is attached.\n output.on('error', (err) => {\n if (err instanceof AbortError)\n return\n if (output.listenerCount('error') === 1)\n throw err\n })\n\n // Start async merge process\n // Errors are forwarded to the stream consumer via destroy.\n mergeChunksToStream(statementResult, auth, manifest, format, output, signal, forceMerge, logger)\n .catch((err) => {\n logger?.error?.(`fetchStream error while streaming statement ${statementId}.`, {\n ...baseLog,\n error: err,\n })\n output.destroy(err as Error)\n })\n\n return output\n}\n\n/**\n * Collect all external link URLs and merge them into output stream\n */\nasync function mergeChunksToStream(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n format: MergeFormat,\n output: PassThrough,\n signal?: AbortSignal,\n forceMerge?: boolean,\n logger?: FetchStreamOptions['logger']\n): Promise<void> {\n const statementId = statementResult.statement_id\n const baseLog = { statementId, manifest, format, forceMerge }\n logger?.info?.(`fetchStream collecting external links for statement ${statementId}.`, baseLog)\n const urls = await collectExternalUrls(statementResult, auth, manifest, signal)\n\n // No external links - close the stream\n if (urls.length === 0) {\n logger?.info?.(`fetchStream no external links found for statement ${statementId}.`, baseLog)\n return void output.end()\n }\n\n // Single URL - pipe directly to output unless forcing merge\n if (urls.length === 1 && !forceMerge) {\n logger?.info?.(`fetchStream piping single external link for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n // Avoid merge-streams overhead for a single URL unless forced.\n return pipeUrlToOutput(urls[0]!, output, signal)\n }\n\n // Merge all URLs using merge-streams\n logger?.info?.(`fetchStream merging ${urls.length} external links for statement ${statementId}.`, {\n ...baseLog,\n urlCount: urls.length,\n })\n return mergeStreamsFromUrls(format, signal ? { urls, output, signal } : { urls, output })\n}\n\nasync function collectExternalUrls(\n statementResult: StatementResult,\n auth: AuthInfo,\n manifest: StatementManifest,\n signal?: AbortSignal\n): Promise<string[]> {\n const chunkUrls = new Map<number, string[]>()\n\n addChunkLinks(chunkUrls, statementResult.result?.external_links)\n\n if (!manifest.total_chunk_count)\n return flattenChunkUrls(chunkUrls)\n\n for (let i = 0; i < manifest.total_chunk_count; i++) {\n if (chunkUrls.has(i))\n continue\n if (signal?.aborted)\n throw new AbortError('Aborted while collecting URLs')\n\n // Chunk metadata contains external link URLs when results are chunked.\n const chunkData = await getChunk(auth, statementResult.statement_id, i, signal)\n addChunkLinks(chunkUrls, chunkData.external_links)\n }\n\n return flattenChunkUrls(chunkUrls)\n}\n\nfunction addChunkLinks(\n chunkUrls: Map<number, string[]>,\n externalLinks?: ExternalLinkInfo[]\n): void {\n if (!externalLinks)\n return\n\n for (const link of externalLinks) {\n if (!isNonEmptyString(link.external_link))\n continue\n\n const existing = chunkUrls.get(link.chunk_index)\n if (existing) {\n existing.push(link.external_link)\n } else {\n chunkUrls.set(link.chunk_index, [link.external_link])\n }\n }\n}\n\nfunction flattenChunkUrls(chunkUrls: Map<number, string[]>): string[] {\n if (chunkUrls.size === 0)\n return []\n\n const sorted = [...chunkUrls.entries()].sort(([a], [b]) => a - b)\n const urls: string[] = []\n for (const [, links] of sorted) {\n urls.push(...links)\n }\n return urls\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n","import type {\n AuthInfo,\n FetchAllOptions,\n FetchRowsOptions,\n RowArray,\n RowObject,\n StatementResult,\n} from '../types.js'\n\nimport { fetchRow } from './fetchRow.js'\n\n/**\n * Fetch all rows from statement result as an array.\n * Only supports INLINE results or JSON_ARRAY external links.\n */\nexport async function fetchAll(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: FetchAllOptions = {}\n): Promise<Array<RowArray | RowObject>> {\n const rows: Array<RowArray | RowObject> = []\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const logContext = { statementId, manifest, requestedFormat: options.format }\n const fetchOptions: FetchRowsOptions = {\n // Collect rows as they are streamed in.\n onEachRow: (row) => {\n rows.push(row)\n },\n }\n const { logger } = options\n\n logger?.info?.(`fetchAll fetching all rows for statement ${statementId}.`, logContext)\n\n if (options.signal)\n fetchOptions.signal = options.signal\n\n if (options.format)\n fetchOptions.format = options.format\n\n if (options.logger)\n fetchOptions.logger = options.logger\n\n if (options.encodeBigInt)\n fetchOptions.encodeBigInt = options.encodeBigInt\n\n if (options.encodeTimestamp)\n fetchOptions.encodeTimestamp = options.encodeTimestamp\n\n await fetchRow(statementResult, auth, fetchOptions)\n logger?.info?.(`fetchAll fetched ${rows.length} rows for statement ${statementId}.`, {\n ...logContext,\n rowCount: rows.length,\n resolvedFormat: options.format ?? manifest?.format,\n })\n return rows\n}\n","import type {\n AuthInfo,\n MergeExternalLinksOptions,\n StatementResult,\n} from '../types.js'\n\nimport { validateSucceededResult } from '../util.js'\nimport { fetchStream } from './fetchStream.js'\n\n/**\n * Merge external links from StatementResult into a single stream,\n * upload it via the provided callback, and return updated StatementResult.\n *\n * If the result is not external links (inline data or empty), returns the original as-is.\n */\nexport async function mergeExternalLinks(\n statementResult: StatementResult,\n auth: AuthInfo,\n options: MergeExternalLinksOptions\n): Promise<StatementResult> {\n const { signal, mergeStreamToExternalLink, forceMerge, logger } = options\n const statementId = statementResult.statement_id\n const manifest = statementResult.manifest\n const externalLinks = statementResult.result?.external_links\n const totalChunks = manifest?.total_chunk_count ?? 0\n const logContext = { statementId, manifest, totalChunks, forceMerge }\n\n // If not external links, return original as-is\n if (!externalLinks) {\n logger?.info?.(`mergeExternalLinks no external links to merge for statement ${statementId}.`, logContext)\n return statementResult\n }\n\n if (!forceMerge) {\n const isSingleChunk = totalChunks <= 1\n\n // Skip merging when a single external link already exists unless forced.\n if (isSingleChunk) {\n logger?.info?.(`mergeExternalLinks skipping merge for single external link in statement ${statementId}.`, {\n ...logContext,\n totalChunks,\n })\n return statementResult\n }\n }\n\n // Get merged stream via fetchStream\n logger?.info?.(`mergeExternalLinks merging external links for statement ${statementId}.`, logContext)\n const stream = fetchStream(statementResult, auth, {\n ...signal ? { signal } : {},\n ...forceMerge !== undefined ? { forceMerge } : {},\n ...logger ? { logger } : {},\n })\n\n // Upload via callback\n logger?.info?.(`mergeExternalLinks uploading merged external link for statement ${statementId}.`, logContext)\n const uploadResult = await mergeStreamToExternalLink(stream)\n logger?.info?.(`mergeExternalLinks uploaded merged external link for statement ${statementId}.`, {\n ...logContext,\n byteCount: uploadResult.byte_count,\n expiration: uploadResult.expiration,\n })\n\n // Build updated StatementResult\n // Manifest must exist for external links; validate before constructing new result.\n const validatedManifest = validateSucceededResult(statementResult)\n const totalRowCount = validatedManifest.total_row_count ?? 0\n\n return {\n statement_id: statementResult.statement_id,\n status: statementResult.status,\n manifest: {\n ...validatedManifest,\n total_chunk_count: 1,\n total_byte_count: uploadResult.byte_count,\n chunks: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n },\n ],\n },\n result: {\n external_links: [\n {\n chunk_index: 0,\n row_offset: 0,\n row_count: totalRowCount,\n byte_count: uploadResult.byte_count,\n external_link: uploadResult.externalLink,\n expiration: uploadResult.expiration,\n },\n ],\n },\n }\n}\n"],"mappings":"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","names":["errorBody","mapped"]}
|