@qualithm/arrow-flight-sql-js 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +6 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +157 -206
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +19 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -9
- package/dist/index.js.map +1 -1
- package/dist/pool.d.ts +3 -3
- package/dist/pool.js +3 -3
- package/dist/proto.d.ts +10 -0
- package/dist/proto.d.ts.map +1 -1
- package/dist/proto.js +15 -0
- package/dist/proto.js.map +1 -1
- package/dist/retry.d.ts +1 -1
- package/dist/runtime.d.ts +82 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +227 -0
- package/dist/runtime.js.map +1 -0
- package/dist/transport-grpc-js.d.ts +58 -0
- package/dist/transport-grpc-js.d.ts.map +1 -0
- package/dist/transport-grpc-js.js +300 -0
- package/dist/transport-grpc-js.js.map +1 -0
- package/dist/transport.d.ts +223 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +35 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +20 -3
package/dist/client.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Modeled after the official Arrow Flight SQL clients (Java, C++, Go).
|
|
6
6
|
*/
|
|
7
7
|
import { type RecordBatch, type Schema, type Table } from "apache-arrow";
|
|
8
|
-
import { type Action, type ActionResult, type ActionType, type CatalogInfo, type ExecuteOptions, type FlightData, type FlightDescriptor, type FlightInfo, type FlightSqlClientOptions, type ForeignKeyInfo, type PrimaryKeyInfo, type SchemaInfo, type SchemaResult, type SubscribeOptions, type TableInfo, type TableType, type Ticket } from "./types";
|
|
8
|
+
import { type Action, type ActionResult, type ActionType, type CatalogInfo, type ExecuteOptions, type FlightData, type FlightDescriptor, type FlightInfo, type FlightSqlClientOptions, type ForeignKeyInfo, type PrimaryKeyInfo, type SchemaInfo, type SchemaResult, type SubscribeOptions, type TableInfo, type TableType, type Ticket } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* Flight SQL client for executing queries and managing data with Arrow Flight SQL servers.
|
|
11
11
|
*
|
|
@@ -30,8 +30,7 @@ import { type Action, type ActionResult, type ActionType, type CatalogInfo, type
|
|
|
30
30
|
*/
|
|
31
31
|
export declare class FlightSqlClient {
|
|
32
32
|
private readonly options;
|
|
33
|
-
private
|
|
34
|
-
private flightService;
|
|
33
|
+
private transport;
|
|
35
34
|
private authToken;
|
|
36
35
|
private connected;
|
|
37
36
|
constructor(options: FlightSqlClientOptions);
|
|
@@ -357,17 +356,15 @@ export declare class FlightSqlClient {
|
|
|
357
356
|
private authenticate;
|
|
358
357
|
private handshake;
|
|
359
358
|
private encodeBasicAuth;
|
|
360
|
-
private createCredentials;
|
|
361
|
-
private waitForReady;
|
|
362
359
|
private createRequestMetadata;
|
|
363
360
|
private cleanup;
|
|
364
361
|
private ensureConnected;
|
|
365
|
-
private wrapGrpcError;
|
|
366
362
|
/**
|
|
367
|
-
*
|
|
368
|
-
*
|
|
363
|
+
* Get the transport, throwing if not connected.
|
|
364
|
+
* This is a helper to avoid non-null assertions after ensureConnected().
|
|
369
365
|
*/
|
|
370
|
-
private
|
|
366
|
+
private getConnectedTransport;
|
|
367
|
+
private wrapTransportError;
|
|
371
368
|
private serializeFlightDescriptor;
|
|
372
369
|
private parseFlightInfo;
|
|
373
370
|
private parseSchemaResult;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
* A TypeScript client for communicating with Arrow Flight SQL servers.
|
|
5
5
|
* Modeled after the official Arrow Flight SQL clients (Java, C++, Go).
|
|
6
6
|
*/
|
|
7
|
-
import * as grpc from "@grpc/grpc-js";
|
|
8
7
|
import { RecordBatchReader } from "apache-arrow";
|
|
9
|
-
import { collectToTable, parseFlightData, tryParseSchema } from "./arrow";
|
|
10
|
-
import { AuthenticationError, ConnectionError, FlightSqlError } from "./errors";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { SubscriptionMessageType, SubscriptionMode } from "./types";
|
|
8
|
+
import { collectToTable, parseFlightData, tryParseSchema } from "./arrow.js";
|
|
9
|
+
import { AuthenticationError, ConnectionError, FlightSqlError } from "./errors.js";
|
|
10
|
+
import { encodeActionClosePreparedStatementRequest, encodeActionCreatePreparedStatementRequest, encodeCommandGetCatalogs, encodeCommandGetDbSchemas, encodeCommandGetExportedKeys, encodeCommandGetImportedKeys, encodeCommandGetPrimaryKeys, encodeCommandGetTables, encodeCommandGetTableTypes, encodeCommandPreparedStatementQuery, encodeCommandStatementQuery, encodeCommandStatementUpdate, getBytesField, parseProtoFields, unwrapAny } from "./proto.js";
|
|
11
|
+
import { getTransportForRuntime } from "./transport-grpc-js.js";
|
|
12
|
+
import { SubscriptionMessageType, SubscriptionMode } from "./types.js";
|
|
14
13
|
// Default configuration values
|
|
15
14
|
const defaultConnectTimeoutMs = 30_000;
|
|
16
15
|
const defaultRequestTimeoutMs = 60_000;
|
|
@@ -38,8 +37,7 @@ const defaultRequestTimeoutMs = 60_000;
|
|
|
38
37
|
*/
|
|
39
38
|
export class FlightSqlClient {
|
|
40
39
|
options;
|
|
41
|
-
|
|
42
|
-
flightService = null;
|
|
40
|
+
transport = null;
|
|
43
41
|
authToken = null;
|
|
44
42
|
connected = false;
|
|
45
43
|
constructor(options) {
|
|
@@ -50,6 +48,10 @@ export class FlightSqlClient {
|
|
|
50
48
|
connectTimeoutMs: options.connectTimeoutMs ?? defaultConnectTimeoutMs,
|
|
51
49
|
requestTimeoutMs: options.requestTimeoutMs ?? defaultRequestTimeoutMs
|
|
52
50
|
};
|
|
51
|
+
// Use provided transport or create one for the runtime
|
|
52
|
+
if (options.transport !== undefined) {
|
|
53
|
+
this.transport = options.transport;
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
// ===========================================================================
|
|
55
57
|
// Connection Lifecycle
|
|
@@ -65,25 +67,17 @@ export class FlightSqlClient {
|
|
|
65
67
|
return;
|
|
66
68
|
}
|
|
67
69
|
try {
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const credentials = this.options.credentials ?? this.createCredentials();
|
|
77
|
-
// Create the gRPC client
|
|
78
|
-
const address = `${this.options.host}:${String(this.options.port)}`;
|
|
79
|
-
this.grpcClient = new this.flightService(address, credentials, {
|
|
80
|
-
"grpc.max_receive_message_length": -1, // Unlimited
|
|
81
|
-
"grpc.max_send_message_length": -1,
|
|
82
|
-
"grpc.keepalive_time_ms": 30_000,
|
|
83
|
-
"grpc.keepalive_timeout_ms": 10_000
|
|
70
|
+
// Create transport if not provided
|
|
71
|
+
this.transport ??= getTransportForRuntime({
|
|
72
|
+
host: this.options.host,
|
|
73
|
+
port: this.options.port,
|
|
74
|
+
tls: this.options.tls,
|
|
75
|
+
credentials: this.options.credentials,
|
|
76
|
+
connectTimeoutMs: this.options.connectTimeoutMs,
|
|
77
|
+
requestTimeoutMs: this.options.requestTimeoutMs
|
|
84
78
|
});
|
|
85
|
-
//
|
|
86
|
-
await this.
|
|
79
|
+
// Connect the transport
|
|
80
|
+
await this.transport.connect();
|
|
87
81
|
// Perform authentication handshake if configured
|
|
88
82
|
if (this.options.auth && this.options.auth.type !== "none") {
|
|
89
83
|
await this.authenticate(this.options.auth);
|
|
@@ -215,12 +209,19 @@ export class FlightSqlClient {
|
|
|
215
209
|
let datasetSchema = null;
|
|
216
210
|
let parameterSchema = null;
|
|
217
211
|
for await (const result of this.doAction(action)) {
|
|
212
|
+
// The result body may be wrapped in a protobuf Any envelope
|
|
213
|
+
// Try to unwrap it first, otherwise parse directly
|
|
214
|
+
let messageBytes = result.body;
|
|
215
|
+
const anyWrapper = unwrapAny(result.body);
|
|
216
|
+
if (anyWrapper) {
|
|
217
|
+
messageBytes = anyWrapper.value;
|
|
218
|
+
}
|
|
218
219
|
// Parse ActionCreatePreparedStatementResult
|
|
219
220
|
// Fields:
|
|
220
221
|
// 1: prepared_statement_handle (bytes)
|
|
221
222
|
// 2: dataset_schema (bytes) - Arrow IPC schema
|
|
222
223
|
// 3: parameter_schema (bytes) - Arrow IPC schema
|
|
223
|
-
const fields = parseProtoFields(
|
|
224
|
+
const fields = parseProtoFields(messageBytes);
|
|
224
225
|
handle = getBytesField(fields, 1);
|
|
225
226
|
const datasetSchemaBytes = getBytesField(fields, 2);
|
|
226
227
|
const parameterSchemaBytes = getBytesField(fields, 3);
|
|
@@ -519,19 +520,19 @@ export class FlightSqlClient {
|
|
|
519
520
|
* @returns FlightInfo with schema and endpoints
|
|
520
521
|
*/
|
|
521
522
|
async getFlightInfo(descriptor) {
|
|
522
|
-
this.
|
|
523
|
-
|
|
524
|
-
const client = this.grpcClient;
|
|
523
|
+
const transport = this.getConnectedTransport();
|
|
524
|
+
try {
|
|
525
525
|
const metadata = this.createRequestMetadata();
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
526
|
+
const rawInfo = await transport.getFlightInfo({
|
|
527
|
+
type: descriptor.type,
|
|
528
|
+
cmd: descriptor.cmd,
|
|
529
|
+
path: descriptor.path
|
|
530
|
+
}, metadata);
|
|
531
|
+
return this.parseFlightInfo(rawInfo);
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
throw this.wrapTransportError(error);
|
|
535
|
+
}
|
|
535
536
|
}
|
|
536
537
|
/**
|
|
537
538
|
* Get the schema for a flight descriptor without fetching data.
|
|
@@ -540,19 +541,19 @@ export class FlightSqlClient {
|
|
|
540
541
|
* @returns Schema result
|
|
541
542
|
*/
|
|
542
543
|
async getSchema(descriptor) {
|
|
543
|
-
this.
|
|
544
|
-
|
|
545
|
-
const client = this.grpcClient;
|
|
544
|
+
const transport = this.getConnectedTransport();
|
|
545
|
+
try {
|
|
546
546
|
const metadata = this.createRequestMetadata();
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
547
|
+
const rawSchema = await transport.getSchema({
|
|
548
|
+
type: descriptor.type,
|
|
549
|
+
cmd: descriptor.cmd,
|
|
550
|
+
path: descriptor.path
|
|
551
|
+
}, metadata);
|
|
552
|
+
return this.parseSchemaResult(rawSchema);
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
throw this.wrapTransportError(error);
|
|
556
|
+
}
|
|
556
557
|
}
|
|
557
558
|
/**
|
|
558
559
|
* Retrieve data for a ticket as an async iterator of FlightData.
|
|
@@ -561,17 +562,20 @@ export class FlightSqlClient {
|
|
|
561
562
|
* @yields FlightData chunks containing dataHeader and dataBody
|
|
562
563
|
*/
|
|
563
564
|
async *doGet(ticket) {
|
|
564
|
-
this.
|
|
565
|
-
const client = this.grpcClient;
|
|
565
|
+
const transport = this.getConnectedTransport();
|
|
566
566
|
const metadata = this.createRequestMetadata();
|
|
567
|
-
const
|
|
568
|
-
const stream = client.doGet(request, metadata);
|
|
567
|
+
const stream = transport.doGet({ ticket: ticket.ticket }, metadata);
|
|
569
568
|
try {
|
|
570
|
-
for await (const data of
|
|
571
|
-
|
|
572
|
-
|
|
569
|
+
for await (const data of stream) {
|
|
570
|
+
yield {
|
|
571
|
+
dataHeader: data.dataHeader,
|
|
572
|
+
dataBody: data.dataBody
|
|
573
|
+
};
|
|
573
574
|
}
|
|
574
575
|
}
|
|
576
|
+
catch (error) {
|
|
577
|
+
throw this.wrapTransportError(error);
|
|
578
|
+
}
|
|
575
579
|
finally {
|
|
576
580
|
stream.cancel();
|
|
577
581
|
}
|
|
@@ -584,16 +588,10 @@ export class FlightSqlClient {
|
|
|
584
588
|
* @returns Async iterator of PutResult messages
|
|
585
589
|
*/
|
|
586
590
|
async *doPut(descriptor, dataStream) {
|
|
587
|
-
this.
|
|
588
|
-
const client = this.grpcClient;
|
|
591
|
+
const transport = this.getConnectedTransport();
|
|
589
592
|
const requestMetadata = this.createRequestMetadata();
|
|
590
593
|
// Create bidirectional stream
|
|
591
|
-
const stream =
|
|
592
|
-
// Use object wrapper to track errors (allows TypeScript to understand mutation)
|
|
593
|
-
const errorState = { error: null };
|
|
594
|
-
stream.on("error", (err) => {
|
|
595
|
-
errorState.error = err;
|
|
596
|
-
});
|
|
594
|
+
const stream = transport.doPut(requestMetadata);
|
|
597
595
|
// Send the first message with the descriptor
|
|
598
596
|
const firstData = await this.getFirstFromIterable(dataStream);
|
|
599
597
|
if (firstData) {
|
|
@@ -606,9 +604,6 @@ export class FlightSqlClient {
|
|
|
606
604
|
}
|
|
607
605
|
// Send remaining data
|
|
608
606
|
for await (const data of dataStream) {
|
|
609
|
-
if (errorState.error) {
|
|
610
|
-
throw this.wrapGrpcError(errorState.error);
|
|
611
|
-
}
|
|
612
607
|
stream.write({
|
|
613
608
|
dataHeader: data.dataHeader,
|
|
614
609
|
dataBody: data.dataBody,
|
|
@@ -619,16 +614,12 @@ export class FlightSqlClient {
|
|
|
619
614
|
stream.end();
|
|
620
615
|
// Read responses
|
|
621
616
|
try {
|
|
622
|
-
for await (const result of
|
|
623
|
-
|
|
624
|
-
yield { appMetadata: putResult.appMetadata };
|
|
617
|
+
for await (const result of stream) {
|
|
618
|
+
yield { appMetadata: result.appMetadata };
|
|
625
619
|
}
|
|
626
620
|
}
|
|
627
621
|
catch (error) {
|
|
628
|
-
|
|
629
|
-
throw this.wrapGrpcError(errorState.error);
|
|
630
|
-
}
|
|
631
|
-
throw error;
|
|
622
|
+
throw this.wrapTransportError(error);
|
|
632
623
|
}
|
|
633
624
|
}
|
|
634
625
|
/**
|
|
@@ -662,25 +653,15 @@ export class FlightSqlClient {
|
|
|
662
653
|
* ```
|
|
663
654
|
*/
|
|
664
655
|
doExchange(descriptor) {
|
|
665
|
-
this.
|
|
666
|
-
const client = this.grpcClient;
|
|
656
|
+
const transport = this.getConnectedTransport();
|
|
667
657
|
const metadata = this.createRequestMetadata();
|
|
668
|
-
const stream =
|
|
669
|
-
// Use object wrapper to track errors
|
|
670
|
-
const errorState = { error: null };
|
|
671
|
-
stream.on("error", (err) => {
|
|
672
|
-
errorState.error = err;
|
|
673
|
-
});
|
|
658
|
+
const stream = transport.doExchange(metadata);
|
|
674
659
|
// Capture references for closure
|
|
675
|
-
const
|
|
660
|
+
const wrapTransportError = this.wrapTransportError.bind(this);
|
|
676
661
|
const serializeFlightDescriptor = this.serializeFlightDescriptor.bind(this);
|
|
677
|
-
const wrapStream = this.wrapStream.bind(this);
|
|
678
662
|
// Create the exchange handle
|
|
679
663
|
const exchange = {
|
|
680
664
|
async send(data) {
|
|
681
|
-
if (errorState.error) {
|
|
682
|
-
throw wrapGrpcError(errorState.error);
|
|
683
|
-
}
|
|
684
665
|
stream.write({
|
|
685
666
|
flightDescriptor: data.flightDescriptor
|
|
686
667
|
? serializeFlightDescriptor(data.flightDescriptor)
|
|
@@ -700,27 +681,23 @@ export class FlightSqlClient {
|
|
|
700
681
|
},
|
|
701
682
|
async *[Symbol.asyncIterator]() {
|
|
702
683
|
try {
|
|
703
|
-
for await (const data of
|
|
704
|
-
const flightData = data;
|
|
684
|
+
for await (const data of stream) {
|
|
705
685
|
yield {
|
|
706
|
-
flightDescriptor:
|
|
686
|
+
flightDescriptor: data.flightDescriptor
|
|
707
687
|
? {
|
|
708
|
-
type:
|
|
709
|
-
cmd:
|
|
710
|
-
path:
|
|
688
|
+
type: data.flightDescriptor.type,
|
|
689
|
+
cmd: data.flightDescriptor.cmd,
|
|
690
|
+
path: data.flightDescriptor.path
|
|
711
691
|
}
|
|
712
692
|
: undefined,
|
|
713
|
-
dataHeader:
|
|
714
|
-
dataBody:
|
|
715
|
-
appMetadata:
|
|
693
|
+
dataHeader: data.dataHeader ?? new Uint8Array(),
|
|
694
|
+
dataBody: data.dataBody ?? new Uint8Array(),
|
|
695
|
+
appMetadata: data.appMetadata
|
|
716
696
|
};
|
|
717
697
|
}
|
|
718
698
|
}
|
|
719
699
|
catch (error) {
|
|
720
|
-
|
|
721
|
-
throw wrapGrpcError(errorState.error);
|
|
722
|
-
}
|
|
723
|
-
throw error;
|
|
700
|
+
throw wrapTransportError(error);
|
|
724
701
|
}
|
|
725
702
|
}
|
|
726
703
|
};
|
|
@@ -779,16 +756,17 @@ export class FlightSqlClient {
|
|
|
779
756
|
* @returns Async iterator of results
|
|
780
757
|
*/
|
|
781
758
|
async *doAction(action) {
|
|
782
|
-
this.
|
|
783
|
-
const client = this.grpcClient;
|
|
759
|
+
const transport = this.getConnectedTransport();
|
|
784
760
|
const metadata = this.createRequestMetadata();
|
|
785
|
-
const
|
|
786
|
-
const stream = client.doAction(request, metadata);
|
|
761
|
+
const stream = transport.doAction({ type: action.type, body: action.body }, metadata);
|
|
787
762
|
try {
|
|
788
|
-
for await (const result of
|
|
789
|
-
yield result;
|
|
763
|
+
for await (const result of stream) {
|
|
764
|
+
yield { body: result.body ?? new Uint8Array() };
|
|
790
765
|
}
|
|
791
766
|
}
|
|
767
|
+
catch (error) {
|
|
768
|
+
throw this.wrapTransportError(error);
|
|
769
|
+
}
|
|
792
770
|
finally {
|
|
793
771
|
stream.cancel();
|
|
794
772
|
}
|
|
@@ -799,13 +777,20 @@ export class FlightSqlClient {
|
|
|
799
777
|
* @returns Array of available action types
|
|
800
778
|
*/
|
|
801
779
|
async listActions() {
|
|
802
|
-
this.
|
|
803
|
-
const client = this.grpcClient;
|
|
780
|
+
const transport = this.getConnectedTransport();
|
|
804
781
|
const metadata = this.createRequestMetadata();
|
|
805
|
-
const stream =
|
|
782
|
+
const stream = transport.listActions(metadata);
|
|
806
783
|
const actions = [];
|
|
807
|
-
|
|
808
|
-
|
|
784
|
+
try {
|
|
785
|
+
for await (const action of stream) {
|
|
786
|
+
actions.push({
|
|
787
|
+
type: action.type,
|
|
788
|
+
description: action.description ?? ""
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
catch (error) {
|
|
793
|
+
throw this.wrapTransportError(error);
|
|
809
794
|
}
|
|
810
795
|
return actions;
|
|
811
796
|
}
|
|
@@ -833,30 +818,35 @@ export class FlightSqlClient {
|
|
|
833
818
|
}
|
|
834
819
|
}
|
|
835
820
|
async handshake(username, password) {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
stream.on("error", (error) => {
|
|
848
|
-
reject(new AuthenticationError("Handshake failed", { cause: error }));
|
|
849
|
-
});
|
|
850
|
-
stream.on("end", () => {
|
|
851
|
-
// Stream ended without response
|
|
852
|
-
});
|
|
853
|
-
// Send handshake request
|
|
854
|
-
stream.write({
|
|
855
|
-
protocolVersion: "1",
|
|
856
|
-
payload: authPayload
|
|
857
|
-
});
|
|
858
|
-
stream.end();
|
|
821
|
+
// Note: Called during connect(), so transport exists but connected flag isn't set yet
|
|
822
|
+
if (this.transport === null) {
|
|
823
|
+
throw new ConnectionError("Transport not initialized");
|
|
824
|
+
}
|
|
825
|
+
const stream = this.transport.handshake();
|
|
826
|
+
// Build BasicAuth payload
|
|
827
|
+
const authPayload = this.encodeBasicAuth(username, password);
|
|
828
|
+
// Send handshake request
|
|
829
|
+
stream.write({
|
|
830
|
+
protocolVersion: 1,
|
|
831
|
+
payload: authPayload
|
|
859
832
|
});
|
|
833
|
+
stream.end();
|
|
834
|
+
// Read response
|
|
835
|
+
try {
|
|
836
|
+
for await (const response of stream) {
|
|
837
|
+
return {
|
|
838
|
+
protocolVersion: BigInt(response.protocolVersion ?? 0),
|
|
839
|
+
payload: response.payload ?? new Uint8Array()
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
throw new AuthenticationError("Handshake failed: no response received");
|
|
843
|
+
}
|
|
844
|
+
catch (error) {
|
|
845
|
+
if (error instanceof AuthenticationError) {
|
|
846
|
+
throw error;
|
|
847
|
+
}
|
|
848
|
+
throw new AuthenticationError("Handshake failed", { cause: error });
|
|
849
|
+
}
|
|
860
850
|
}
|
|
861
851
|
encodeBasicAuth(username, password) {
|
|
862
852
|
// Simple encoding: "username:password" as UTF-8 bytes
|
|
@@ -865,101 +855,62 @@ export class FlightSqlClient {
|
|
|
865
855
|
return encoder.encode(`${username}:${password}`);
|
|
866
856
|
}
|
|
867
857
|
// ===========================================================================
|
|
868
|
-
// Private:
|
|
858
|
+
// Private: Transport Helpers
|
|
869
859
|
// ===========================================================================
|
|
870
|
-
createCredentials() {
|
|
871
|
-
if (this.options.tls) {
|
|
872
|
-
return grpc.credentials.createSsl();
|
|
873
|
-
}
|
|
874
|
-
return grpc.credentials.createInsecure();
|
|
875
|
-
}
|
|
876
|
-
async waitForReady() {
|
|
877
|
-
return new Promise((resolve, reject) => {
|
|
878
|
-
const deadline = Date.now() + this.options.connectTimeoutMs;
|
|
879
|
-
const client = this.grpcClient;
|
|
880
|
-
if (!client) {
|
|
881
|
-
reject(new ConnectionError("gRPC client not initialized"));
|
|
882
|
-
return;
|
|
883
|
-
}
|
|
884
|
-
client.waitForReady(deadline, (error) => {
|
|
885
|
-
if (error) {
|
|
886
|
-
reject(new ConnectionError("Connection timeout", { cause: error }));
|
|
887
|
-
}
|
|
888
|
-
else {
|
|
889
|
-
resolve();
|
|
890
|
-
}
|
|
891
|
-
});
|
|
892
|
-
});
|
|
893
|
-
}
|
|
894
860
|
createRequestMetadata() {
|
|
895
|
-
const metadata =
|
|
861
|
+
const metadata = {};
|
|
896
862
|
// Add auth token if present
|
|
897
863
|
if (this.authToken !== null && this.authToken !== "") {
|
|
898
|
-
metadata.
|
|
864
|
+
metadata.authorization = `Bearer ${this.authToken}`;
|
|
899
865
|
}
|
|
900
866
|
// Add custom metadata from options
|
|
901
867
|
if (this.options.metadata) {
|
|
902
868
|
for (const [key, value] of Object.entries(this.options.metadata)) {
|
|
903
|
-
metadata
|
|
869
|
+
metadata[key] = value;
|
|
904
870
|
}
|
|
905
871
|
}
|
|
906
872
|
return metadata;
|
|
907
873
|
}
|
|
908
874
|
cleanup() {
|
|
909
|
-
if (this.
|
|
910
|
-
this.
|
|
911
|
-
this.
|
|
875
|
+
if (this.transport) {
|
|
876
|
+
this.transport.close();
|
|
877
|
+
this.transport = null;
|
|
912
878
|
}
|
|
913
|
-
this.flightService = null;
|
|
914
879
|
this.authToken = null;
|
|
915
880
|
this.connected = false;
|
|
916
881
|
}
|
|
917
882
|
ensureConnected() {
|
|
918
|
-
if (!this.connected) {
|
|
883
|
+
if (!this.connected || this.transport === null) {
|
|
919
884
|
throw new ConnectionError("Client is not connected. Call connect() first.");
|
|
920
885
|
}
|
|
921
886
|
}
|
|
922
|
-
wrapGrpcError(error) {
|
|
923
|
-
const message = error.details || error.message;
|
|
924
|
-
switch (error.code) {
|
|
925
|
-
case grpc.status.UNAUTHENTICATED:
|
|
926
|
-
return new AuthenticationError(message, { cause: error });
|
|
927
|
-
case grpc.status.UNAVAILABLE:
|
|
928
|
-
case grpc.status.DEADLINE_EXCEEDED:
|
|
929
|
-
return new ConnectionError(message, { cause: error });
|
|
930
|
-
case grpc.status.OK:
|
|
931
|
-
case grpc.status.CANCELLED:
|
|
932
|
-
case grpc.status.UNKNOWN:
|
|
933
|
-
case grpc.status.INVALID_ARGUMENT:
|
|
934
|
-
case grpc.status.NOT_FOUND:
|
|
935
|
-
case grpc.status.ALREADY_EXISTS:
|
|
936
|
-
case grpc.status.PERMISSION_DENIED:
|
|
937
|
-
case grpc.status.RESOURCE_EXHAUSTED:
|
|
938
|
-
case grpc.status.FAILED_PRECONDITION:
|
|
939
|
-
case grpc.status.ABORTED:
|
|
940
|
-
case grpc.status.OUT_OF_RANGE:
|
|
941
|
-
case grpc.status.UNIMPLEMENTED:
|
|
942
|
-
case grpc.status.INTERNAL:
|
|
943
|
-
case grpc.status.DATA_LOSS:
|
|
944
|
-
return new FlightSqlError(message, { cause: error });
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
// ===========================================================================
|
|
948
|
-
// Private: Streaming Helpers
|
|
949
|
-
// ===========================================================================
|
|
950
887
|
/**
|
|
951
|
-
*
|
|
952
|
-
*
|
|
888
|
+
* Get the transport, throwing if not connected.
|
|
889
|
+
* This is a helper to avoid non-null assertions after ensureConnected().
|
|
953
890
|
*/
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
yield data;
|
|
958
|
-
}
|
|
891
|
+
getConnectedTransport() {
|
|
892
|
+
if (!this.connected || this.transport === null) {
|
|
893
|
+
throw new ConnectionError("Client is not connected. Call connect() first.");
|
|
959
894
|
}
|
|
960
|
-
|
|
961
|
-
|
|
895
|
+
return this.transport;
|
|
896
|
+
}
|
|
897
|
+
wrapTransportError(error) {
|
|
898
|
+
// Handle TransportError with gRPC status codes
|
|
899
|
+
const transportError = error;
|
|
900
|
+
const message = transportError.details ?? error.message;
|
|
901
|
+
if (transportError.code !== undefined) {
|
|
902
|
+
// gRPC status codes
|
|
903
|
+
switch (transportError.code) {
|
|
904
|
+
case 16: // UNAUTHENTICATED
|
|
905
|
+
return new AuthenticationError(message, { cause: error });
|
|
906
|
+
case 14: // UNAVAILABLE
|
|
907
|
+
case 4: // DEADLINE_EXCEEDED
|
|
908
|
+
return new ConnectionError(message, { cause: error });
|
|
909
|
+
default:
|
|
910
|
+
return new FlightSqlError(message, { cause: error });
|
|
911
|
+
}
|
|
962
912
|
}
|
|
913
|
+
return new FlightSqlError(message, { cause: error });
|
|
963
914
|
}
|
|
964
915
|
// ===========================================================================
|
|
965
916
|
// Private: Serialization Helpers
|