@clickhouse/client-common 1.20.0 → 1.21.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/README.md +11 -11
- package/dist/clickhouse_types.js +6 -6
- package/dist/clickhouse_types.js.map +1 -1
- package/dist/client.d.ts +19 -9
- package/dist/client.js +231 -43
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +54 -10
- package/dist/config.js +42 -38
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +12 -8
- package/dist/data_formatter/format_query_params.js +21 -21
- package/dist/data_formatter/format_query_params.js.map +1 -1
- package/dist/data_formatter/format_query_settings.d.ts +1 -1
- package/dist/data_formatter/format_query_settings.js +4 -4
- package/dist/data_formatter/format_query_settings.js.map +1 -1
- package/dist/data_formatter/formatter.d.ts +2 -2
- package/dist/data_formatter/formatter.js +28 -28
- package/dist/data_formatter/formatter.js.map +1 -1
- package/dist/data_formatter/index.d.ts +3 -3
- package/dist/data_formatter/index.js.map +1 -1
- package/dist/error/error.js +18 -4
- package/dist/error/error.js.map +1 -1
- package/dist/error/index.d.ts +1 -1
- package/dist/error/index.js.map +1 -1
- package/dist/index.d.ts +21 -20
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +29 -14
- package/dist/logger.js +40 -27
- package/dist/logger.js.map +1 -1
- package/dist/parse/column_types.d.ts +10 -10
- package/dist/parse/column_types.js +97 -92
- package/dist/parse/column_types.js.map +1 -1
- package/dist/parse/index.d.ts +2 -2
- package/dist/parse/index.js.map +1 -1
- package/dist/parse/json_handling.js.map +1 -1
- package/dist/result.d.ts +4 -4
- package/dist/settings.d.ts +47 -30
- package/dist/settings.js +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/tracing.d.ts +146 -0
- package/dist/tracing.js +76 -0
- package/dist/tracing.js.map +1 -0
- package/dist/utils/connection.d.ts +1 -1
- package/dist/utils/connection.js +7 -7
- package/dist/utils/connection.js.map +1 -1
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/multipart.d.ts +34 -0
- package/dist/utils/multipart.js +81 -0
- package/dist/utils/multipart.js.map +1 -0
- package/dist/utils/sleep.js.map +1 -1
- package/dist/utils/stream.js +4 -4
- package/dist/utils/stream.js.map +1 -1
- package/dist/utils/url.d.ts +5 -2
- package/dist/utils/url.js +21 -16
- package/dist/utils/url.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/settings.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DataFormat } from
|
|
1
|
+
import type { DataFormat } from "./data_formatter";
|
|
2
2
|
/**
|
|
3
3
|
* @see {@link https://github.com/ClickHouse/ClickHouse/blob/46ed4f6cdf68fbbdc59fbe0f0bfa9a361cc0dec1/src/Core/Settings.h}
|
|
4
4
|
* @see {@link https://github.com/ClickHouse/ClickHouse/blob/eae2667a1c29565c801be0ffd465f8bfcffe77ef/src/Storages/MergeTree/MergeTreeSettings.h}
|
|
@@ -1602,6 +1602,23 @@ interface ClickHouseHTTPSettings {
|
|
|
1602
1602
|
* Additionally, this is useful when executing DDLs on clustered environments,
|
|
1603
1603
|
* as the client will receive the response only when the DDL is applied on all nodes of the cluster. */
|
|
1604
1604
|
wait_end_of_query: Bool;
|
|
1605
|
+
/** Number of bytes in the result to buffer in the server memory.
|
|
1606
|
+
* If the result body is larger than this threshold, the buffer is written to the HTTP channel,
|
|
1607
|
+
* and the remaining data is sent directly to the HTTP channel. */
|
|
1608
|
+
buffer_size: UInt64;
|
|
1609
|
+
/** If enabled, the server compresses the data it sends to the client using the internal ClickHouse
|
|
1610
|
+
* compression format (not a standard HTTP one). The compressed data has a non-standard format,
|
|
1611
|
+
* and the `clickhouse-compressor` program is required to work with it.
|
|
1612
|
+
* For standard HTTP (gzip) compression, use the `compression` client configuration option instead. */
|
|
1613
|
+
compress: Bool;
|
|
1614
|
+
/** If enabled, the server decompresses the data passed in the POST request body, expecting it to be
|
|
1615
|
+
* compressed using the internal ClickHouse compression format (not a standard HTTP one). */
|
|
1616
|
+
decompress: Bool;
|
|
1617
|
+
/** Can be passed as the quota key (any string).
|
|
1618
|
+
* @see https://clickhouse.com/docs/operations/quotas */
|
|
1619
|
+
quota_key: string;
|
|
1620
|
+
/** If enabled, include the stack trace in the response body when an exception occurs. */
|
|
1621
|
+
stacktrace: Bool;
|
|
1605
1622
|
/** Format to use if a SELECT query is executed without a FORMAT clause.
|
|
1606
1623
|
* Only useful for the {@link ClickHouseClient.exec} method,
|
|
1607
1624
|
* as {@link ClickHouseClient.query} method always attaches this clause. */
|
|
@@ -1641,7 +1658,7 @@ export interface MergeTreeSettings {
|
|
|
1641
1658
|
/** Check columns or columns by hash for sampling are unsigned integer. */
|
|
1642
1659
|
check_sample_column_is_correct?: Bool;
|
|
1643
1660
|
/** Is the Replicated Merge cleanup has to be done automatically at each merge or manually (possible values are 'Always'/'Never' (default)) */
|
|
1644
|
-
clean_deleted_rows?:
|
|
1661
|
+
clean_deleted_rows?: "Always" | "Never";
|
|
1645
1662
|
/** Minimum period to clean old queue logs, blocks hashes and parts. */
|
|
1646
1663
|
cleanup_delay_period?: UInt64;
|
|
1647
1664
|
/** Add uniformly distributed value from 0 to x seconds to cleanup_delay_period to avoid thundering herd effect and subsequent DoS of ZooKeeper in case of very large number of tables. */
|
|
@@ -1942,32 +1959,32 @@ export declare class SettingsMap {
|
|
|
1942
1959
|
toString(): string;
|
|
1943
1960
|
static from(record: Record<string, string>): SettingsMap;
|
|
1944
1961
|
}
|
|
1945
|
-
export type LoadBalancing =
|
|
1946
|
-
export type TotalsMode =
|
|
1947
|
-
export type DistributedProductMode =
|
|
1948
|
-
export type LogsLevel =
|
|
1949
|
-
export type LogQueriesType =
|
|
1950
|
-
export type DefaultTableEngine =
|
|
1951
|
-
export type MySQLDataTypesSupport =
|
|
1952
|
-
export type DistributedDDLOutputMode =
|
|
1953
|
-
export type ShortCircuitFunctionEvaluation =
|
|
1954
|
-
export type TransactionsWaitCSNMode =
|
|
1955
|
-
export type EscapingRule =
|
|
1956
|
-
export type DateTimeOutputFormat =
|
|
1957
|
-
export type DateTimeInputFormat =
|
|
1958
|
-
export type MsgPackUUIDRepresentation =
|
|
1959
|
-
export type OverflowMode =
|
|
1960
|
-
export type OverflowModeGroupBy = OverflowMode |
|
|
1961
|
-
export type JoinStrictness =
|
|
1962
|
-
export type JoinAlgorithm =
|
|
1963
|
-
export type Dialect =
|
|
1964
|
-
export type CapnProtoEnumComparingMode =
|
|
1965
|
-
export type ParquetCompression =
|
|
1966
|
-
export type ArrowCompression =
|
|
1967
|
-
export type ORCCompression =
|
|
1968
|
-
export type SetOperationMode =
|
|
1969
|
-
export type LocalFSReadMethod =
|
|
1970
|
-
export type ParallelReplicasCustomKeyFilterType =
|
|
1971
|
-
export type IntervalOutputFormat =
|
|
1972
|
-
export type ParquetVersion =
|
|
1962
|
+
export type LoadBalancing = "random" | "nearest_hostname" | "in_order" | "first_or_random" | "round_robin";
|
|
1963
|
+
export type TotalsMode = "before_having" | "after_having_inclusive" | "after_having_exclusive" | "after_having_auto";
|
|
1964
|
+
export type DistributedProductMode = "deny" | "local" | "global" | "allow";
|
|
1965
|
+
export type LogsLevel = "none" | "fatal" | "error" | "warning" | "information" | "debug" | "trace" | "test";
|
|
1966
|
+
export type LogQueriesType = "QUERY_START" | "QUERY_FINISH" | "EXCEPTION_BEFORE_START" | "EXCEPTION_WHILE_PROCESSING";
|
|
1967
|
+
export type DefaultTableEngine = "Memory" | "ReplicatedMergeTree" | "ReplacingMergeTree" | "MergeTree" | "StripeLog" | "ReplicatedReplacingMergeTree" | "Log" | "None";
|
|
1968
|
+
export type MySQLDataTypesSupport = "" | "date2String" | "date2Date32" | "datetime64" | "decimal";
|
|
1969
|
+
export type DistributedDDLOutputMode = "never_throw" | "null_status_on_timeout" | "throw" | "none";
|
|
1970
|
+
export type ShortCircuitFunctionEvaluation = "force_enable" | "disable" | "enable";
|
|
1971
|
+
export type TransactionsWaitCSNMode = "wait_unknown" | "wait" | "async";
|
|
1972
|
+
export type EscapingRule = "CSV" | "JSON" | "Quoted" | "Raw" | "XML" | "Escaped" | "None";
|
|
1973
|
+
export type DateTimeOutputFormat = "simple" | "iso" | "unix_timestamp";
|
|
1974
|
+
export type DateTimeInputFormat = "best_effort_us" | "best_effort" | "basic";
|
|
1975
|
+
export type MsgPackUUIDRepresentation = "ext" | "str" | "bin";
|
|
1976
|
+
export type OverflowMode = "break" | "throw";
|
|
1977
|
+
export type OverflowModeGroupBy = OverflowMode | "any";
|
|
1978
|
+
export type JoinStrictness = "ANY" | "ALL" | "";
|
|
1979
|
+
export type JoinAlgorithm = "prefer_partial_merge" | "hash" | "parallel_hash" | "partial_merge" | "auto" | "default" | "direct" | "full_sorting_merge" | "grace_hash";
|
|
1980
|
+
export type Dialect = "clickhouse" | "kusto" | "kusto_auto" | "prql";
|
|
1981
|
+
export type CapnProtoEnumComparingMode = "by_names" | "by_values" | "by_names_case_insensitive";
|
|
1982
|
+
export type ParquetCompression = "none" | "snappy" | "zstd" | "gzip" | "lz4" | "brotli";
|
|
1983
|
+
export type ArrowCompression = "none" | "lz4_frame" | "zstd";
|
|
1984
|
+
export type ORCCompression = "none" | "snappy" | "zstd" | "gzip" | "lz4";
|
|
1985
|
+
export type SetOperationMode = "" | "ALL" | "DISTINCT";
|
|
1986
|
+
export type LocalFSReadMethod = "read" | "pread" | "mmap";
|
|
1987
|
+
export type ParallelReplicasCustomKeyFilterType = "default" | "range";
|
|
1988
|
+
export type IntervalOutputFormat = "kusto" | "numeric";
|
|
1989
|
+
export type ParquetVersion = "1.0" | "2.4" | "2.6" | "2.latest";
|
|
1973
1990
|
export {};
|
package/dist/settings.js
CHANGED
package/dist/settings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":";;;AA+6DA,MAAa,WAAW;IACL,MAAM,CAAyB;IAChD,YAAoB,MAA8B;QAChD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;aACnC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;aAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,MAA8B;QACxC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;CACF;AAfD,kCAeC"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal, dependency-free tracer interface that is a structural subset of
|
|
3
|
+
* the {@link https://opentelemetry.io/docs/specs/otel/trace/api/#tracer OpenTelemetry `Tracer` API}.
|
|
4
|
+
*
|
|
5
|
+
* The shapes below are deliberately declared so that a raw OpenTelemetry
|
|
6
|
+
* tracer (the object returned by `trace.getTracer(...)` from
|
|
7
|
+
* `@opentelemetry/api`) is assignable to {@link ClickHouseTracer} **as-is**,
|
|
8
|
+
* with no adapter and no casts:
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { trace } from '@opentelemetry/api'
|
|
12
|
+
* const client = createClient({ tracer: trace.getTracer('clickhouse-js') })
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* At the same time, the client itself imports nothing from OpenTelemetry -
|
|
16
|
+
* non-OTEL backends (Prometheus counters, an `EventEmitter`, a plain logger)
|
|
17
|
+
* can implement the same small surface directly.
|
|
18
|
+
*
|
|
19
|
+
* When a {@link ClickHouseTracer} is provided via
|
|
20
|
+
* {@link BaseClickHouseClientConfigOptions.tracer}, the client runs each
|
|
21
|
+
* tracked operation (`query`, `command`, `exec`, `insert`, `ping`) inside
|
|
22
|
+
* {@link ClickHouseTracer.startActiveSpan}, mutates the provided
|
|
23
|
+
* {@link ClickHouseSpan} during the operation
|
|
24
|
+
* ({@link ClickHouseSpan.setAttributes}, {@link ClickHouseSpan.setStatus},
|
|
25
|
+
* {@link ClickHouseSpan.recordException}), and calls
|
|
26
|
+
* {@link ClickHouseSpan.end} exactly once. For `command`, `exec`, `insert`,
|
|
27
|
+
* and `ping`, the span ends when the operation settles (regardless of
|
|
28
|
+
* outcome). For `query`, two spans are emitted: the `clickhouse.query` span
|
|
29
|
+
* ends as soon as the HTTP response headers are received; a child
|
|
30
|
+
* `clickhouse.query.stream` span is then handed to the `ResultSet`, which
|
|
31
|
+
* tracks the streaming progress and ends it when the response stream is fully
|
|
32
|
+
* consumed, closed, or fails.
|
|
33
|
+
*
|
|
34
|
+
* Calls are inlined directly into the client's hot path - there is no
|
|
35
|
+
* defensive wrapper around them. Any exception thrown by a tracer or span
|
|
36
|
+
* method will propagate up to the caller of the corresponding client method
|
|
37
|
+
* (`query`/`command`/`exec`/`insert`/`ping`). Implementations are therefore
|
|
38
|
+
* expected to be non-throwing; a trivial e2e test against your tracer is
|
|
39
|
+
* usually enough to catch regressions.
|
|
40
|
+
*/
|
|
41
|
+
export interface ClickHouseTracer<TSpan extends ClickHouseSpan = ClickHouseSpan> {
|
|
42
|
+
/**
|
|
43
|
+
* Called when a tracked operation begins. Same shape as OpenTelemetry's
|
|
44
|
+
* `Tracer.startActiveSpan(name, options, fn)` overload: implementations
|
|
45
|
+
* must invoke `fn` with the new span and return `fn`'s result untouched.
|
|
46
|
+
* The client runs the entire operation (an `async` function) inside `fn`,
|
|
47
|
+
* mutates the span during the operation, and ends it exactly once.
|
|
48
|
+
*
|
|
49
|
+
* @note The callback is asynchronous under the hood: the client keeps using
|
|
50
|
+
* the span across `await` points inside `fn`. For OpenTelemetry, active-span
|
|
51
|
+
* context propagation across those `await`s requires the
|
|
52
|
+
* `AsyncLocalStorageContextManager` (from
|
|
53
|
+
* `@opentelemetry/context-async-hooks`) to be registered - which is the
|
|
54
|
+
* default context manager in the OpenTelemetry Node.js SDK
|
|
55
|
+
* (`@opentelemetry/sdk-node` / `NodeTracerProvider`). With it in place,
|
|
56
|
+
* auto-instrumented child spans (e.g. from
|
|
57
|
+
* `@opentelemetry/instrumentation-http`) are parented under the ClickHouse
|
|
58
|
+
* operation span.
|
|
59
|
+
*/
|
|
60
|
+
startActiveSpan<T>(name: string, options: ClickHouseSpanOptions, fn: (span: TSpan) => T): T;
|
|
61
|
+
}
|
|
62
|
+
/** Structural subset of the OpenTelemetry `Span` interface - a real OTEL
|
|
63
|
+
* `Span` is assignable to this type as-is. Methods are declared as
|
|
64
|
+
* `void`-returning, so OTEL's chainable `this`-returning methods remain
|
|
65
|
+
* compatible. */
|
|
66
|
+
export interface ClickHouseSpan {
|
|
67
|
+
/** Attach additional attributes to an in-flight span. Called at least once
|
|
68
|
+
* for every span - typically right before {@link ClickHouseSpan.end} -
|
|
69
|
+
* with operation-specific attributes such as `clickhouse.request.query_id`. */
|
|
70
|
+
setAttributes(attributes: ClickHouseSpanAttributes): void;
|
|
71
|
+
/** Set the logical status of the span. The codes are value-identical to
|
|
72
|
+
* OTEL's `SpanStatusCode`; see {@link ClickHouseSpanStatusCode}. */
|
|
73
|
+
setStatus(status: ClickHouseSpanStatus): void;
|
|
74
|
+
/** Attach an exception that occurred during the span. Called before
|
|
75
|
+
* {@link ClickHouseSpan.setStatus} with the `ERROR` code, before
|
|
76
|
+
* {@link ClickHouseSpan.end}. Non-`Error` throwables are normalized
|
|
77
|
+
* to `Error` by the client before this call. */
|
|
78
|
+
recordException(error: Error): void;
|
|
79
|
+
/** Called exactly once per span, regardless of success or failure. */
|
|
80
|
+
end(): void;
|
|
81
|
+
}
|
|
82
|
+
/** Structural subset of OTEL's `SpanOptions`. */
|
|
83
|
+
export interface ClickHouseSpanOptions {
|
|
84
|
+
/** Value-identical to OTEL's `SpanKind`; see {@link ClickHouseSpanKind}.
|
|
85
|
+
* The client always passes {@link ClickHouseSpanKind.CLIENT}, per the
|
|
86
|
+
* OTEL database semantic conventions. */
|
|
87
|
+
kind?: number;
|
|
88
|
+
/** Initial attributes for the span. */
|
|
89
|
+
attributes?: ClickHouseSpanAttributes;
|
|
90
|
+
}
|
|
91
|
+
/** Span status; `code` values are listed in {@link ClickHouseSpanStatusCode}
|
|
92
|
+
* and are value-identical to OTEL's `SpanStatusCode`. */
|
|
93
|
+
export interface ClickHouseSpanStatus {
|
|
94
|
+
code: number;
|
|
95
|
+
message?: string;
|
|
96
|
+
}
|
|
97
|
+
/** Value-identical to OTEL's `SpanStatusCode`, so non-OTEL implementations
|
|
98
|
+
* do not have to deal with magic numbers. */
|
|
99
|
+
export declare const ClickHouseSpanStatusCode: {
|
|
100
|
+
readonly UNSET: 0;
|
|
101
|
+
readonly OK: 1;
|
|
102
|
+
readonly ERROR: 2;
|
|
103
|
+
};
|
|
104
|
+
/** Value-identical to OTEL's `SpanKind`. The client only ever uses
|
|
105
|
+
* {@link ClickHouseSpanKind.CLIENT}. */
|
|
106
|
+
export declare const ClickHouseSpanKind: {
|
|
107
|
+
readonly INTERNAL: 0;
|
|
108
|
+
readonly SERVER: 1;
|
|
109
|
+
readonly CLIENT: 2;
|
|
110
|
+
readonly PRODUCER: 3;
|
|
111
|
+
readonly CONSUMER: 4;
|
|
112
|
+
};
|
|
113
|
+
/** Free-form attribute bag; a subset of OTEL's `Attributes`. Implementations
|
|
114
|
+
* should be tolerant of `undefined` values (skip them) and stringify
|
|
115
|
+
* non-primitive values as needed. */
|
|
116
|
+
export type ClickHouseSpanAttributes = Record<string, string | number | boolean | undefined>;
|
|
117
|
+
/** Span name constants used by the client when starting spans.
|
|
118
|
+
* Exposed so that adapters and tests can match on them. */
|
|
119
|
+
export declare const ClickHouseSpanNames: {
|
|
120
|
+
readonly query: "clickhouse.query";
|
|
121
|
+
/** A child of {@link ClickHouseSpanNames.query} that covers the lifetime
|
|
122
|
+
* of the `ResultSet` stream - from the first byte read to full
|
|
123
|
+
* consumption, cancellation, or failure. Ends with
|
|
124
|
+
* `clickhouse.response.decoded_bytes` and (for row-streaming paths)
|
|
125
|
+
* `db.response.returned_rows`. */
|
|
126
|
+
readonly query_stream: "clickhouse.query.stream";
|
|
127
|
+
readonly command: "clickhouse.command";
|
|
128
|
+
readonly exec: "clickhouse.exec";
|
|
129
|
+
readonly insert: "clickhouse.insert";
|
|
130
|
+
readonly ping: "clickhouse.ping";
|
|
131
|
+
};
|
|
132
|
+
export type ClickHouseSpanName = (typeof ClickHouseSpanNames)[keyof typeof ClickHouseSpanNames];
|
|
133
|
+
/** Shared no-op span handed out by {@link NoopClickHouseTracer}. @internal */
|
|
134
|
+
export declare const NoopClickHouseSpan: ClickHouseSpan;
|
|
135
|
+
/** No-op tracer assigned once at client creation when no tracer is
|
|
136
|
+
* configured, so the hot path stays branch-free (monomorphic call sites
|
|
137
|
+
* that the JIT can inline). @internal */
|
|
138
|
+
export declare const NoopClickHouseTracer: ClickHouseTracer;
|
|
139
|
+
/** Records the exception on the span and marks it with the ERROR status,
|
|
140
|
+
* normalizing non-`Error` throwables to `Error`.
|
|
141
|
+
*
|
|
142
|
+
* Sets the {@link https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/#error-type `error.type`}
|
|
143
|
+
* attribute to the error class name (e.g. `ClickHouseError`, `TypeError`),
|
|
144
|
+
* and, for server-side errors ({@link ClickHouseError}), the numeric server
|
|
145
|
+
* error code as `clickhouse.error.code`. */
|
|
146
|
+
export declare function recordSpanError(span: ClickHouseSpan, err: unknown): void;
|
package/dist/tracing.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NoopClickHouseTracer = exports.NoopClickHouseSpan = exports.ClickHouseSpanNames = exports.ClickHouseSpanKind = exports.ClickHouseSpanStatusCode = void 0;
|
|
4
|
+
exports.recordSpanError = recordSpanError;
|
|
5
|
+
const error_1 = require("./error");
|
|
6
|
+
/** Value-identical to OTEL's `SpanStatusCode`, so non-OTEL implementations
|
|
7
|
+
* do not have to deal with magic numbers. */
|
|
8
|
+
exports.ClickHouseSpanStatusCode = {
|
|
9
|
+
UNSET: 0,
|
|
10
|
+
OK: 1,
|
|
11
|
+
ERROR: 2,
|
|
12
|
+
};
|
|
13
|
+
/** Value-identical to OTEL's `SpanKind`. The client only ever uses
|
|
14
|
+
* {@link ClickHouseSpanKind.CLIENT}. */
|
|
15
|
+
exports.ClickHouseSpanKind = {
|
|
16
|
+
INTERNAL: 0,
|
|
17
|
+
SERVER: 1,
|
|
18
|
+
CLIENT: 2,
|
|
19
|
+
PRODUCER: 3,
|
|
20
|
+
CONSUMER: 4,
|
|
21
|
+
};
|
|
22
|
+
/** Span name constants used by the client when starting spans.
|
|
23
|
+
* Exposed so that adapters and tests can match on them. */
|
|
24
|
+
exports.ClickHouseSpanNames = {
|
|
25
|
+
query: "clickhouse.query",
|
|
26
|
+
/** A child of {@link ClickHouseSpanNames.query} that covers the lifetime
|
|
27
|
+
* of the `ResultSet` stream - from the first byte read to full
|
|
28
|
+
* consumption, cancellation, or failure. Ends with
|
|
29
|
+
* `clickhouse.response.decoded_bytes` and (for row-streaming paths)
|
|
30
|
+
* `db.response.returned_rows`. */
|
|
31
|
+
query_stream: "clickhouse.query.stream",
|
|
32
|
+
command: "clickhouse.command",
|
|
33
|
+
exec: "clickhouse.exec",
|
|
34
|
+
insert: "clickhouse.insert",
|
|
35
|
+
ping: "clickhouse.ping",
|
|
36
|
+
};
|
|
37
|
+
const noop = () => undefined;
|
|
38
|
+
/** Shared no-op span handed out by {@link NoopClickHouseTracer}. @internal */
|
|
39
|
+
exports.NoopClickHouseSpan = {
|
|
40
|
+
setAttributes: noop,
|
|
41
|
+
setStatus: noop,
|
|
42
|
+
recordException: noop,
|
|
43
|
+
end: noop,
|
|
44
|
+
};
|
|
45
|
+
/** No-op tracer assigned once at client creation when no tracer is
|
|
46
|
+
* configured, so the hot path stays branch-free (monomorphic call sites
|
|
47
|
+
* that the JIT can inline). @internal */
|
|
48
|
+
exports.NoopClickHouseTracer = {
|
|
49
|
+
startActiveSpan: (_name, _options, fn) => fn(exports.NoopClickHouseSpan),
|
|
50
|
+
};
|
|
51
|
+
/** Records the exception on the span and marks it with the ERROR status,
|
|
52
|
+
* normalizing non-`Error` throwables to `Error`.
|
|
53
|
+
*
|
|
54
|
+
* Sets the {@link https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/#error-type `error.type`}
|
|
55
|
+
* attribute to the error class name (e.g. `ClickHouseError`, `TypeError`),
|
|
56
|
+
* and, for server-side errors ({@link ClickHouseError}), the numeric server
|
|
57
|
+
* error code as `clickhouse.error.code`. */
|
|
58
|
+
function recordSpanError(span, err) {
|
|
59
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
60
|
+
const attributes = {
|
|
61
|
+
"error.type": error.constructor.name,
|
|
62
|
+
};
|
|
63
|
+
if (error instanceof error_1.ClickHouseError) {
|
|
64
|
+
const code = Number(error.code);
|
|
65
|
+
attributes["clickhouse.error.code"] = Number.isNaN(code)
|
|
66
|
+
? error.code
|
|
67
|
+
: code;
|
|
68
|
+
}
|
|
69
|
+
span.setAttributes(attributes);
|
|
70
|
+
span.recordException(error);
|
|
71
|
+
span.setStatus({
|
|
72
|
+
code: exports.ClickHouseSpanStatusCode.ERROR,
|
|
73
|
+
message: error.message,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=tracing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":";;;AA+KA,0CAiBC;AAhMD,mCAA0C;AA4G1C;8CAC8C;AACjC,QAAA,wBAAwB,GAAG;IACtC,KAAK,EAAE,CAAC;IACR,EAAE,EAAE,CAAC;IACL,KAAK,EAAE,CAAC;CACA,CAAC;AAEX;yCACyC;AAC5B,QAAA,kBAAkB,GAAG;IAChC,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;CACH,CAAC;AAUX;4DAC4D;AAC/C,QAAA,mBAAmB,GAAG;IACjC,KAAK,EAAE,kBAAkB;IACzB;;;;uCAImC;IACnC,YAAY,EAAE,yBAAyB;IACvC,OAAO,EAAE,oBAAoB;IAC7B,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,mBAAmB;IAC3B,IAAI,EAAE,iBAAiB;CACf,CAAC;AAIX,MAAM,IAAI,GAAG,GAAS,EAAE,CAAC,SAAS,CAAC;AACnC,8EAA8E;AACjE,QAAA,kBAAkB,GAAmB;IAChD,aAAa,EAAE,IAAI;IACnB,SAAS,EAAE,IAAI;IACf,eAAe,EAAE,IAAI;IACrB,GAAG,EAAE,IAAI;CACV,CAAC;AAEF;;0CAE0C;AAC7B,QAAA,oBAAoB,GAAqB;IACpD,eAAe,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,0BAAkB,CAAC;CACjE,CAAC;AAEF;;;;;;6CAM6C;AAC7C,SAAgB,eAAe,CAAC,IAAoB,EAAE,GAAY;IAChE,MAAM,KAAK,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,MAAM,UAAU,GAA6B;QAC3C,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,IAAI;KACrC,CAAC;IACF,IAAI,KAAK,YAAY,uBAAe,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,UAAU,CAAC,uBAAuB,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;YACtD,CAAC,CAAC,KAAK,CAAC,IAAI;YACZ,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IACD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/B,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,CAAC,SAAS,CAAC;QACb,IAAI,EAAE,gCAAwB,CAAC,KAAK;QACpC,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClickHouseSettings } from
|
|
1
|
+
import type { ClickHouseSettings } from "../settings";
|
|
2
2
|
export type HttpHeader = number | string | string[];
|
|
3
3
|
export type HttpHeaders = Record<string, HttpHeader | undefined>;
|
|
4
4
|
export declare function withCompressionHeaders({ headers, enable_request_compression, enable_response_compression, }: {
|
package/dist/utils/connection.js
CHANGED
|
@@ -9,8 +9,8 @@ exports.isCredentialsAuth = isCredentialsAuth;
|
|
|
9
9
|
function withCompressionHeaders({ headers, enable_request_compression, enable_response_compression, }) {
|
|
10
10
|
return {
|
|
11
11
|
...headers,
|
|
12
|
-
...(enable_response_compression ? {
|
|
13
|
-
...(enable_request_compression ? {
|
|
12
|
+
...(enable_response_compression ? { "Accept-Encoding": "gzip" } : {}),
|
|
13
|
+
...(enable_request_compression ? { "Content-Encoding": "gzip" } : {}),
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
function withHttpSettings(clickhouse_settings, compression) {
|
|
@@ -27,13 +27,13 @@ function isSuccessfulResponse(statusCode) {
|
|
|
27
27
|
return Boolean(statusCode && 200 <= statusCode && statusCode < 300);
|
|
28
28
|
}
|
|
29
29
|
function isJWTAuth(auth) {
|
|
30
|
-
return auth !== null && typeof auth ===
|
|
30
|
+
return auth !== null && typeof auth === "object" && "access_token" in auth;
|
|
31
31
|
}
|
|
32
32
|
function isCredentialsAuth(auth) {
|
|
33
33
|
return (auth !== null &&
|
|
34
|
-
typeof auth ===
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
typeof auth === "object" &&
|
|
35
|
+
"username" in auth &&
|
|
36
|
+
"password" in auth);
|
|
37
37
|
}
|
|
38
|
-
exports.EXCEPTION_TAG_HEADER_NAME =
|
|
38
|
+
exports.EXCEPTION_TAG_HEADER_NAME = "x-clickhouse-exception-tag";
|
|
39
39
|
//# sourceMappingURL=connection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/utils/connection.ts"],"names":[],"mappings":";;;AAKA,wDAcC;AAED,4CAYC;AAED,oDAEC;AAED,8BAEC;AAED,8CASC;AA/CD,SAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,0BAA0B,EAC1B,2BAA2B,GAK5B;IACC,OAAO;QACL,GAAG,OAAO;QACV,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtE,
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/utils/connection.ts"],"names":[],"mappings":";;;AAKA,wDAcC;AAED,4CAYC;AAED,oDAEC;AAED,8BAEC;AAED,8CASC;AA/CD,SAAgB,sBAAsB,CAAC,EACrC,OAAO,EACP,0BAA0B,EAC1B,2BAA2B,GAK5B;IACC,OAAO;QACL,GAAG,OAAO;QACV,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,GAAG,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtE,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAC9B,mBAAwC,EACxC,WAAqB;IAErB,OAAO;QACL,GAAG,CAAC,WAAW;YACb,CAAC,CAAC;gBACE,uBAAuB,EAAE,CAAC;aAC3B;YACH,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,mBAAmB;KACvB,CAAC;AACJ,CAAC;AAED,SAAgB,oBAAoB,CAAC,UAAmB;IACtD,OAAO,OAAO,CAAC,UAAU,IAAI,GAAG,IAAI,UAAU,IAAI,UAAU,GAAG,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,SAAgB,SAAS,CAAC,IAAa;IACrC,OAAO,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,cAAc,IAAI,IAAI,CAAC;AAC7E,CAAC;AAED,SAAgB,iBAAiB,CAC/B,IAAa;IAEb,OAAO,CACL,IAAI,KAAK,IAAI;QACb,OAAO,IAAI,KAAK,QAAQ;QACxB,UAAU,IAAI,IAAI;QAClB,UAAU,IAAI,IAAI,CACnB,CAAC;AACJ,CAAC;AAEY,QAAA,yBAAyB,GAAG,4BAA4B,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
1
|
+
export * from "./connection";
|
|
2
|
+
export * from "./multipart";
|
|
3
|
+
export * from "./sleep";
|
|
4
|
+
export * from "./stream";
|
|
5
|
+
export * from "./url";
|
package/dist/utils/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./connection"), exports);
|
|
18
|
+
__exportStar(require("./multipart"), exports);
|
|
18
19
|
__exportStar(require("./sleep"), exports);
|
|
19
20
|
__exportStar(require("./stream"), exports);
|
|
20
21
|
__exportStar(require("./url"), exports);
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,8CAA4B;AAC5B,0CAAwB;AACxB,2CAAyB;AACzB,wCAAsB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query parameters are URL-encoded into the request URL as `param_*` entries.
|
|
3
|
+
* Once their encoded length passes this budget, {@link serializeQueryParamsForUrl}
|
|
4
|
+
* returns null so that they are routed through the multipart body instead, keeping
|
|
5
|
+
* oversized payloads out of the URL where HTTP intermediaries (nginx, AWS ALB,
|
|
6
|
+
* CloudFront) reject them with HTTP 414 or 400. The threshold leaves ample
|
|
7
|
+
* headroom under common request line limits.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MAX_URL_BIND_PARAM_LENGTH = 4096;
|
|
10
|
+
/**
|
|
11
|
+
* Early-return variant of the `param_*` serialization performed by
|
|
12
|
+
* {@link toSearchParams}: serializes {@link query_params} into `param_*`
|
|
13
|
+
* URL entries, returning them so the caller can reuse the result without
|
|
14
|
+
* serializing the params a second time, or returns null as soon as the
|
|
15
|
+
* URL-encoded length exceeds {@link MAX_URL_BIND_PARAM_LENGTH} — in which
|
|
16
|
+
* case the params should be sent as a multipart/form-data body instead.
|
|
17
|
+
*/
|
|
18
|
+
export declare function serializeQueryParamsForUrl(query_params: Record<string, unknown>): [string, string][] | null;
|
|
19
|
+
/**
|
|
20
|
+
* Builds a multipart/form-data body from a record of named string parts.
|
|
21
|
+
*
|
|
22
|
+
* Example output:
|
|
23
|
+
*
|
|
24
|
+
* --BOUNDARY\r\n
|
|
25
|
+
* Content-Disposition: form-data; name="query"\r\n
|
|
26
|
+
* \r\n
|
|
27
|
+
* SELECT * FROM t WHERE x IN {values:Array(String)}\r\n
|
|
28
|
+
* --BOUNDARY\r\n
|
|
29
|
+
* Content-Disposition: form-data; name="param_values"\r\n
|
|
30
|
+
* \r\n
|
|
31
|
+
* ['a@b.com','c@d.com']\r\n
|
|
32
|
+
* --BOUNDARY--\r\n
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildMultipartBody(parts: Record<string, string>, boundary: string): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_URL_BIND_PARAM_LENGTH = void 0;
|
|
4
|
+
exports.serializeQueryParamsForUrl = serializeQueryParamsForUrl;
|
|
5
|
+
exports.buildMultipartBody = buildMultipartBody;
|
|
6
|
+
const data_formatter_1 = require("../data_formatter");
|
|
7
|
+
const SAFE_PART_NAME = /^[A-Za-z0-9_.-]+$/;
|
|
8
|
+
/**
|
|
9
|
+
* Query parameters are URL-encoded into the request URL as `param_*` entries.
|
|
10
|
+
* Once their encoded length passes this budget, {@link serializeQueryParamsForUrl}
|
|
11
|
+
* returns null so that they are routed through the multipart body instead, keeping
|
|
12
|
+
* oversized payloads out of the URL where HTTP intermediaries (nginx, AWS ALB,
|
|
13
|
+
* CloudFront) reject them with HTTP 414 or 400. The threshold leaves ample
|
|
14
|
+
* headroom under common request line limits.
|
|
15
|
+
*/
|
|
16
|
+
exports.MAX_URL_BIND_PARAM_LENGTH = 4096;
|
|
17
|
+
/**
|
|
18
|
+
* Early-return variant of the `param_*` serialization performed by
|
|
19
|
+
* {@link toSearchParams}: serializes {@link query_params} into `param_*`
|
|
20
|
+
* URL entries, returning them so the caller can reuse the result without
|
|
21
|
+
* serializing the params a second time, or returns null as soon as the
|
|
22
|
+
* URL-encoded length exceeds {@link MAX_URL_BIND_PARAM_LENGTH} — in which
|
|
23
|
+
* case the params should be sent as a multipart/form-data body instead.
|
|
24
|
+
*/
|
|
25
|
+
function serializeQueryParamsForUrl(query_params) {
|
|
26
|
+
const entries = [];
|
|
27
|
+
// Raw length is a lower bound on the encoded length, so large payloads
|
|
28
|
+
// short-circuit without materializing the encoded string.
|
|
29
|
+
let rawLength = 0;
|
|
30
|
+
for (const [key, value] of Object.entries(query_params)) {
|
|
31
|
+
const name = `param_${key}`;
|
|
32
|
+
const formatted = (0, data_formatter_1.formatQueryParams)({ value });
|
|
33
|
+
rawLength += name.length + formatted.length;
|
|
34
|
+
if (rawLength > exports.MAX_URL_BIND_PARAM_LENGTH) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
entries.push([name, formatted]);
|
|
38
|
+
}
|
|
39
|
+
// Measure the exact encoded length, accounting for percent-encoding expansion.
|
|
40
|
+
if (new URLSearchParams(entries).toString().length > exports.MAX_URL_BIND_PARAM_LENGTH) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return entries;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Builds a multipart/form-data body from a record of named string parts.
|
|
47
|
+
*
|
|
48
|
+
* Example output:
|
|
49
|
+
*
|
|
50
|
+
* --BOUNDARY\r\n
|
|
51
|
+
* Content-Disposition: form-data; name="query"\r\n
|
|
52
|
+
* \r\n
|
|
53
|
+
* SELECT * FROM t WHERE x IN {values:Array(String)}\r\n
|
|
54
|
+
* --BOUNDARY\r\n
|
|
55
|
+
* Content-Disposition: form-data; name="param_values"\r\n
|
|
56
|
+
* \r\n
|
|
57
|
+
* ['a@b.com','c@d.com']\r\n
|
|
58
|
+
* --BOUNDARY--\r\n
|
|
59
|
+
*/
|
|
60
|
+
function buildMultipartBody(parts, boundary) {
|
|
61
|
+
const chunks = [];
|
|
62
|
+
// Part names are validated against SAFE_PART_NAME to prevent header injection
|
|
63
|
+
// (a name could otherwise smuggle CRLF or quotes into the Content-Disposition
|
|
64
|
+
// line). Part values are intentionally NOT validated/escaped: the only way a
|
|
65
|
+
// value could forge a part delimiter is by containing the boundary, and the
|
|
66
|
+
// boundary is a random UUID generated per request by the caller, so it cannot
|
|
67
|
+
// be predicted or collided with by user-supplied input.
|
|
68
|
+
for (const [name, value] of Object.entries(parts)) {
|
|
69
|
+
if (!SAFE_PART_NAME.test(name)) {
|
|
70
|
+
throw new Error(`Invalid multipart part name: "${name}". ` +
|
|
71
|
+
`Part names must match ${SAFE_PART_NAME}.`);
|
|
72
|
+
}
|
|
73
|
+
chunks.push(`--${boundary}\r\n` +
|
|
74
|
+
`Content-Disposition: form-data; name="${name}"\r\n` +
|
|
75
|
+
`\r\n` +
|
|
76
|
+
`${value}\r\n`);
|
|
77
|
+
}
|
|
78
|
+
chunks.push(`--${boundary}--\r\n`);
|
|
79
|
+
return chunks.join("");
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=multipart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/utils/multipart.ts"],"names":[],"mappings":";;;AAsBA,gEAuBC;AAiBD,gDA8BC;AA5FD,sDAAsD;AAEtD,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAE3C;;;;;;;GAOG;AACU,QAAA,yBAAyB,GAAG,IAAI,CAAC;AAE9C;;;;;;;GAOG;AACH,SAAgB,0BAA0B,CACxC,YAAqC;IAErC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,uEAAuE;IACvE,0DAA0D;IAC1D,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,SAAS,GAAG,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAA,kCAAiB,EAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;QAC5C,IAAI,SAAS,GAAG,iCAAyB,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,+EAA+E;IAC/E,IACE,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,iCAAyB,EAC1E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,kBAAkB,CAChC,KAA6B,EAC7B,QAAgB;IAEhB,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,8EAA8E;IAC9E,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,8EAA8E;IAC9E,wDAAwD;IACxD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,KAAK;gBACxC,yBAAyB,cAAc,GAAG,CAC7C,CAAC;QACJ,CAAC;QACD,MAAM,CAAC,IAAI,CACT,KAAK,QAAQ,MAAM;YACjB,yCAAyC,IAAI,OAAO;YACpD,MAAM;YACN,GAAG,KAAK,MAAM,CACjB,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,QAAQ,CAAC,CAAC;IAEnC,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/utils/sleep.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":";;AAGA,sBAMC;AATD;;GAEG;AACI,KAAK,UAAU,KAAK,CAAC,EAAU;IACpC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../src/utils/sleep.ts"],"names":[],"mappings":";;AAGA,sBAMC;AATD;;GAEG;AACI,KAAK,UAAU,KAAK,CAAC,EAAU;IACpC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAClB,CAAC,EAAE,EAAE,CAAC,CACP,CAAC;AACJ,CAAC"}
|
package/dist/utils/stream.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CARET_RETURN = void 0;
|
|
4
4
|
exports.extractErrorAtTheEndOfChunk = extractErrorAtTheEndOfChunk;
|
|
5
5
|
const error_1 = require("../error");
|
|
6
|
-
const EXCEPTION_MARKER =
|
|
6
|
+
const EXCEPTION_MARKER = "__exception__";
|
|
7
7
|
const NEWLINE = 0x0a;
|
|
8
8
|
exports.CARET_RETURN = 0x0d;
|
|
9
9
|
/**
|
|
@@ -28,15 +28,15 @@ function extractErrorAtTheEndOfChunk(chunk, exceptionTag) {
|
|
|
28
28
|
2; // \r\n
|
|
29
29
|
let errMsgLenStartIdx = chunk.length - bytesCountAfterErrLenHint;
|
|
30
30
|
if (errMsgLenStartIdx < 1) {
|
|
31
|
-
return new Error(
|
|
31
|
+
return new Error("there was an error in the stream, but the last chunk is malformed");
|
|
32
32
|
}
|
|
33
33
|
do {
|
|
34
34
|
--errMsgLenStartIdx;
|
|
35
35
|
} while (chunk[errMsgLenStartIdx] !== NEWLINE);
|
|
36
|
-
const textDecoder = new TextDecoder(
|
|
36
|
+
const textDecoder = new TextDecoder("utf-8");
|
|
37
37
|
const errMsgLen = parseInt(textDecoder.decode(chunk.subarray(errMsgLenStartIdx, -bytesCountAfterErrLenHint)));
|
|
38
38
|
if (isNaN(errMsgLen) || errMsgLen <= 0) {
|
|
39
|
-
return new Error(
|
|
39
|
+
return new Error("there was an error in the stream; failed to parse the message length");
|
|
40
40
|
}
|
|
41
41
|
const errMsg = textDecoder.decode(chunk.subarray(errMsgLenStartIdx - errMsgLen + 1, // skipping the newline character
|
|
42
42
|
errMsgLenStartIdx));
|
package/dist/utils/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/utils/stream.ts"],"names":[],"mappings":";;;AAoBA,kEAiDC;AArED,
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/utils/stream.ts"],"names":[],"mappings":";;;AAoBA,kEAiDC;AArED,oCAAsC;AAEtC,MAAM,gBAAgB,GAAG,eAAe,CAAC;AAEzC,MAAM,OAAO,GAAG,IAAa,CAAC;AACjB,QAAA,YAAY,GAAG,IAAa,CAAC;AAE1C;;;;;;;;;;;;GAYG;AACH,SAAgB,2BAA2B,CACzC,KAAiB,EACjB,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,yBAAyB,GAC7B,CAAC,GAAG,QAAQ;YACZ,gBAAgB,CAAC,MAAM,GAAG,gBAAgB;YAC1C,CAAC,GAAG,OAAO;YACX,YAAY,CAAC,MAAM,GAAG,gCAAgC;YACtD,CAAC,CAAC,CAAC,OAAO;QAEZ,IAAI,iBAAiB,GAAG,KAAK,CAAC,MAAM,GAAG,yBAAyB,CAAC;QACjE,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,KAAK,CACd,mEAAmE,CACpE,CAAC;QACJ,CAAC;QAED,GAAG,CAAC;YACF,EAAE,iBAAiB,CAAC;QACtB,CAAC,QAAQ,KAAK,CAAC,iBAAiB,CAAC,KAAK,OAAO,EAAE;QAE/C,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;QAE7C,MAAM,SAAS,GAAG,QAAQ,CACxB,WAAW,CAAC,MAAM,CAChB,KAAK,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,yBAAyB,CAAC,CAC9D,CACF,CAAC;QAEF,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,KAAK,CACd,sEAAsE,CACvE,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAC/B,KAAK,CAAC,QAAQ,CACZ,iBAAiB,GAAG,SAAS,GAAG,CAAC,EAAE,iCAAiC;QACpE,iBAAiB,CAClB,CACF,CAAC;QAEF,OAAO,IAAA,kBAAU,EAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8DAA8D;QAC9D,OAAO,GAAY,CAAC;IACtB,CAAC;AACH,CAAC"}
|
package/dist/utils/url.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClickHouseSettings } from
|
|
1
|
+
import type { ClickHouseSettings } from "../settings";
|
|
2
2
|
export declare function transformUrl({ url, pathname, searchParams, }: {
|
|
3
3
|
url: URL;
|
|
4
4
|
pathname?: string;
|
|
@@ -8,10 +8,13 @@ interface ToSearchParamsOptions {
|
|
|
8
8
|
database: string | undefined;
|
|
9
9
|
clickhouse_settings?: ClickHouseSettings;
|
|
10
10
|
query_params?: Record<string, unknown>;
|
|
11
|
+
/** Pre-serialized `param_*` entries (e.g. from {@link serializeQueryParamsForUrl});
|
|
12
|
+
* used as-is instead of serializing {@link query_params} again. */
|
|
13
|
+
param_entries?: [string, string][];
|
|
11
14
|
query?: string;
|
|
12
15
|
session_id?: string;
|
|
13
16
|
query_id: string;
|
|
14
17
|
role?: string | Array<string>;
|
|
15
18
|
}
|
|
16
|
-
export declare function toSearchParams({ database, query, query_params, clickhouse_settings, session_id, query_id, role, }: ToSearchParamsOptions): URLSearchParams;
|
|
19
|
+
export declare function toSearchParams({ database, query, query_params, param_entries, clickhouse_settings, session_id, query_id, role, }: ToSearchParamsOptions): URLSearchParams;
|
|
17
20
|
export {};
|