@wavehouse/sdk 0.1.0 → 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/index.d.cts CHANGED
@@ -241,7 +241,22 @@ interface Column {
241
241
  name: string;
242
242
  type: string;
243
243
  is_nullable: boolean;
244
+ /** Whether the column declares any default at all — see `default_kind`. */
244
245
  has_default: boolean;
246
+ /**
247
+ * How the default is declared, when there is one: `DEFAULT`, `MATERIALIZED`,
248
+ * `ALIAS` or `EPHEMERAL`. Omitted when the column declares none.
249
+ *
250
+ * `MATERIALIZED` and `ALIAS` columns are computed by ClickHouse and cannot be
251
+ * inserted — a record naming one is rejected — so they never appear in an
252
+ * ingest envelope or an SSE `schema` frame, though they are still reported
253
+ * here and are still queryable.
254
+ */
255
+ default_kind?: string;
256
+ /** 1-based ordinal in the table's declaration order — the order `columns` itself is in. Always present. */
257
+ position: number;
258
+ /** The column's DEFAULT expression, absent when it declares none. */
259
+ default_expression?: string;
245
260
  }
246
261
  interface TableSchema {
247
262
  name: string;
@@ -298,17 +313,24 @@ interface ParamDef {
298
313
  }
299
314
  interface Policy {
300
315
  default_role?: string;
316
+ admin_role?: string;
301
317
  tables: Record<string, TablePolicy>;
302
318
  }
303
- interface TablePolicy {
304
- select?: Record<string, RolePermissions>;
305
- insert?: Record<string, RolePermissions>;
306
- }
319
+ /**
320
+ * Access control for one table, keyed by role name. A role appears once per
321
+ * table and states what it may do; omit `select` to deny reads, omit `insert`
322
+ * to deny writes.
323
+ */
324
+ type TablePolicy = Record<string, RolePermissions>;
307
325
  interface RolePermissions {
326
+ select?: SelectPermissions;
327
+ insert?: InsertPermissions;
328
+ }
329
+ /** A role's read grant on a table. */
330
+ interface SelectPermissions {
308
331
  allow_columns?: string[];
309
332
  deny_columns?: string[];
310
333
  filter?: Record<string, PolicyFilter>;
311
- check?: Record<string, PolicyFilter>;
312
334
  allowed_aggregations?: string[];
313
335
  denied_aggregations?: string[];
314
336
  /** Caps the query result LIMIT. 0 = no limit. */
@@ -328,6 +350,12 @@ interface RolePermissions {
328
350
  */
329
351
  max_memory_usage?: number | string;
330
352
  }
353
+ /** A role's write grant on a table. */
354
+ interface InsertPermissions {
355
+ allow_columns?: string[];
356
+ deny_columns?: string[];
357
+ check?: Record<string, PolicyFilter>;
358
+ }
331
359
  interface PolicyFilter {
332
360
  _eq?: string;
333
361
  _neq?: string;
@@ -335,8 +363,31 @@ interface PolicyFilter {
335
363
  _lt?: string;
336
364
  _in?: string;
337
365
  }
338
- interface ValidationResult {
339
- valid: boolean;
366
+ /** One validation finding from the server's settings directory. */
367
+ interface SettingsFinding {
368
+ severity: "error" | "warning";
369
+ /**
370
+ * Settings file the finding is about; absent for directory-level findings.
371
+ * In a directory of tenant folders it leads with the folder
372
+ * (`acme/policies.json`).
373
+ */
374
+ file?: string;
375
+ /** Dotted JSON path within the file; absent for whole-file findings. */
376
+ path?: string;
377
+ message: string;
378
+ }
379
+ /** Body of POST /v1/ops/settings/reload. */
380
+ interface SettingsReloadResult {
381
+ /**
382
+ * Whether everything the reload covered was adopted; false leaves the
383
+ * previous settings in effect. Over a directory of tenant folders false can
384
+ * mean adopted in part: the tenants with an error among their `findings`
385
+ * were not adopted and are no longer served, and the rest were — `findings`
386
+ * carries every folder's warnings too.
387
+ */
388
+ adopted: boolean;
389
+ /** Every finding from the validation pass (warnings included on success). */
390
+ findings: SettingsFinding[];
340
391
  }
341
392
  /**
342
393
  * Options for a single call, passed to `.fetch()`.
@@ -364,6 +415,24 @@ interface PipeRequestOptions {
364
415
  /** Not supported on pipes — pass `limit` as a pipe parameter instead. */
365
416
  limit?: never;
366
417
  }
418
+ /**
419
+ * Options for a call to one of the admin routes that address a tenant:
420
+ * `wh.pipes.list()`, `wh.pipes.get()`, `wh.settings.reload()`,
421
+ * `wh.schema.list()`, `wh.schema.refresh()`, `wh.from(t).schema()`,
422
+ * `wh.dlq.list()`, `wh.dlq.table()` and `wh.sql()`.
423
+ */
424
+ interface OpsRequestOptions {
425
+ signal?: AbortSignal;
426
+ /**
427
+ * The tenant the call addresses, sent as `?tenant=`. The admin routes ignore
428
+ * the `X-Tenant-ID` header, so `options.headers` cannot select one. Omitted,
429
+ * the reads, the refresh and `sql()` serve the default tenant (`0`) and
430
+ * `reload()` reloads every tenant. An id the server does not accept — the
431
+ * empty string included — is a `400`, never a silent fallback to the
432
+ * default.
433
+ */
434
+ tenant?: string;
435
+ }
367
436
  interface StreamOptions {
368
437
  since?: string;
369
438
  signal?: AbortSignal;
@@ -433,14 +502,13 @@ declare class DLQNamespace {
433
502
  private readonly _ctx;
434
503
  private readonly _createStream;
435
504
  constructor(ctx: HttpContext, createStream: CreateStreamFn$3);
436
- /** Get DLQ statistics (message counts per table). */
437
- list(opts?: {
438
- signal?: AbortSignal;
439
- }): Promise<Result<DLQStats>>;
440
- /** Get DLQ stats filtered by table name. */
441
- table(name: string, opts?: {
442
- signal?: AbortSignal;
443
- }): Promise<Result<DLQStats>>;
505
+ /**
506
+ * Get DLQ statistics (message counts per table) — of `opts.tenant`, the
507
+ * default tenant without it. A tenant with no dead-letter queue is a `404`.
508
+ */
509
+ list(opts?: OpsRequestOptions): Promise<Result<DLQStats>>;
510
+ /** Get DLQ stats filtered by table name — of `opts.tenant`, the default tenant without it. */
511
+ table(name: string, opts?: OpsRequestOptions): Promise<Result<DLQStats>>;
444
512
  /** Subscribe to live DLQ events. */
445
513
  stream(opts?: StreamOptions): StreamController;
446
514
  }
@@ -466,58 +534,63 @@ declare class PipeRef<Row = Record<string, unknown>> implements PromiseLike<Resu
466
534
  stream(opts?: StreamOptions): StreamController<Row>;
467
535
  then<TResult1 = Result<Row[]>, TResult2 = never>(onfulfilled?: ((value: Result<Row[]>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
468
536
  }
469
- /** Admin namespace for managing named query pipes. */
537
+ /**
538
+ * Admin namespace for reading named query pipes.
539
+ *
540
+ * Pipes are defined in the server's settings directory (`pipes.json`, with
541
+ * every `allowed_roles` entry declared in `roles.json`); the files are the only
542
+ * way to define or change a pipe. Edit the files and the server re-adopts them on change, on
543
+ * SIGHUP, or on `wh.settings.reload()` (POST /v1/ops/settings/reload).
544
+ */
470
545
  declare class PipesNamespace {
471
546
  private readonly _ctx;
472
547
  constructor(ctx: HttpContext);
473
- /** List all registered pipes. */
474
- list(opts?: {
475
- signal?: AbortSignal;
476
- }): Promise<Result<Pipe[]>>;
477
- /** Get a single pipe definition by name. */
478
- get(name: string, opts?: {
479
- signal?: AbortSignal;
480
- }): Promise<Result<Pipe>>;
481
- /** Create or update a pipe. */
482
- set(name: string, def: Omit<Pipe, "name">, opts?: {
483
- signal?: AbortSignal;
484
- }): Promise<Result<void>>;
485
- /** Delete a pipe by name. */
486
- delete(name: string, opts?: {
487
- signal?: AbortSignal;
488
- }): Promise<Result<void>>;
548
+ /** List all registered pipes — of `opts.tenant`, the default tenant without it. */
549
+ list(opts?: OpsRequestOptions): Promise<Result<Pipe[]>>;
550
+ /** Get a single pipe definition by name — of `opts.tenant`, the default tenant without it. */
551
+ get(name: string, opts?: OpsRequestOptions): Promise<Result<Pipe>>;
489
552
  }
490
553
 
491
- /** Namespace for access control policy management. Requires the admin role (the configured `admin_role`, `"admin"` by default). */
492
- declare class PolicyNamespace {
554
+ /** Namespace for schema introspection. */
555
+ declare class SchemaNamespace {
493
556
  private readonly _ctx;
494
557
  constructor(ctx: HttpContext);
495
- /** Get the current access control policy. */
496
- get(opts?: {
497
- signal?: AbortSignal;
498
- }): Promise<Result<Policy>>;
499
- /** Replace the entire access control policy. */
500
- set(policy: Policy, opts?: {
501
- signal?: AbortSignal;
502
- }): Promise<Result<void>>;
503
- /** Validate a policy without applying it (dry run). */
504
- validate(policy: Policy, opts?: {
505
- signal?: AbortSignal;
506
- }): Promise<Result<ValidationResult>>;
558
+ /**
559
+ * List all table schemas discovered from ClickHouse — `opts.tenant`'s, the
560
+ * default tenant's without it. A `503` with `Retry-After` is a tenant whose
561
+ * first discovery has not succeeded yet.
562
+ */
563
+ list(opts?: OpsRequestOptions): Promise<Result<Schemas>>;
564
+ /**
565
+ * Force a schema refresh from ClickHouse system.columns — of `opts.tenant`,
566
+ * the default tenant without it.
567
+ */
568
+ refresh(opts?: OpsRequestOptions): Promise<Result<void>>;
507
569
  }
508
570
 
509
- /** Namespace for schema introspection. */
510
- declare class SchemaNamespace {
571
+ /**
572
+ * Namespace for the server's hot-reloadable settings directory. Requires the
573
+ * admin role (the configured `admin_role`, `"admin"` by default).
574
+ *
575
+ * Policy (`policies.json`), roles (`roles.json`), and pipes (`pipes.json`)
576
+ * are defined in that directory; files are the only write path. The server
577
+ * re-adopts them on file change and on SIGHUP, and `reload()` triggers the
578
+ * same path on demand.
579
+ */
580
+ declare class SettingsNamespace {
511
581
  private readonly _ctx;
512
582
  constructor(ctx: HttpContext);
513
- /** List all table schemas discovered from ClickHouse. */
514
- list(opts?: {
515
- signal?: AbortSignal;
516
- }): Promise<Result<Schemas>>;
517
- /** Force a schema refresh from ClickHouse system.columns. */
518
- refresh(opts?: {
519
- signal?: AbortSignal;
520
- }): Promise<Result<void>>;
583
+ /**
584
+ * Re-validate and adopt the settings directory (POST /v1/ops/settings/reload).
585
+ * Resolves with `{ adopted: true, findings }` when adopted (warnings
586
+ * included); a rejected directory is a 422 error whose `details` carries the
587
+ * same `{ adopted: false, findings }` body, and the previous settings stay
588
+ * in effect.
589
+ *
590
+ * `opts.tenant` reloads that tenant's folder alone; without it the whole
591
+ * directory is reloaded.
592
+ */
593
+ reload(opts?: OpsRequestOptions): Promise<Result<SettingsReloadResult>>;
521
594
  }
522
595
 
523
596
  /** Namespace for the SDK's content-free server-online check. */
@@ -662,8 +735,10 @@ declare class TableRef<Row = Record<string, unknown>> {
662
735
  * rest of the batch — per-record outcomes come back in the result
663
736
  * (`failed` / `results`), and `ok` is true only when every record succeeded.
664
737
  *
665
- * The array path sends one request regardless of size; bounded-concurrency
666
- * chunking of very large arrays is tracked separately (#196). For NDJSON you
738
+ * The array path sends one request regardless of size, so it is bound by the
739
+ * server's 16 MiB request-body cap (an over-cap array is a `413` with nothing
740
+ * ingested); bounded-concurrency chunking of very large arrays is tracked
741
+ * separately (#196). For NDJSON you
667
742
  * already have (a file or stream), use {@link insertNDJSON}.
668
743
  */
669
744
  insert(data: Partial<Row> | Partial<Row>[], opts?: {
@@ -675,9 +750,11 @@ declare class TableRef<Row = Record<string, unknown>> {
675
750
  * file or a stream produced by another system. For in-memory rows, prefer
676
751
  * {@link insert}.
677
752
  *
678
- * Non-string sources are read fully into memory before sending (the server
679
- * streams the parse). Returns the same per-record batch summary as an array
680
- * `insert`.
753
+ * Non-string sources are read fully into memory before sending. The server
754
+ * buffers the whole body too, so the request-body cap applies to NDJSON
755
+ * exactly as to any other shape — an upload over it is a `413` with nothing
756
+ * ingested, and must be split across several calls. Returns the same
757
+ * per-record batch summary as an array `insert`.
681
758
  */
682
759
  insertNDJSON(source: NDJSONSource, opts?: {
683
760
  signal?: AbortSignal;
@@ -689,10 +766,8 @@ declare class TableRef<Row = Record<string, unknown>> {
689
766
  * as the success arm with `ok = failed === 0`.
690
767
  */
691
768
  private _sendNDJSON;
692
- /** Fetch the schema for this table. */
693
- schema(opts?: {
694
- signal?: AbortSignal;
695
- }): Promise<Result<TableSchema>>;
769
+ /** Fetch the schema for this table — under `opts.tenant`, the default tenant without it. */
770
+ schema(opts?: OpsRequestOptions): Promise<Result<TableSchema>>;
696
771
  /** Subscribe to live events for this table. */
697
772
  stream(opts?: StreamOptions): StreamController<Row>;
698
773
  }
@@ -704,14 +779,14 @@ declare class WaveHouseClient<DB extends Database = Database> {
704
779
  readonly _ctx: HttpContext;
705
780
  /** Schema introspection namespace. */
706
781
  readonly schema: SchemaNamespace;
707
- /** Access control policy namespace (admin). */
708
- readonly policy: PolicyNamespace;
709
782
  /** Dead Letter Queue namespace. */
710
783
  readonly dlq: DLQNamespace;
711
784
  /** System health/readiness namespace. */
712
785
  readonly sys: SysNamespace;
713
786
  /** Named query pipes admin namespace. */
714
787
  readonly pipes: PipesNamespace;
788
+ /** Settings directory namespace (admin). */
789
+ readonly settings: SettingsNamespace;
715
790
  constructor(config: ClientConfig<DB>);
716
791
  /** Get a table reference for building queries, inserts, and streams. */
717
792
  from<T extends TableName<DB>>(table: T): TableRef<RowType<DB, T>>;
@@ -723,15 +798,15 @@ declare class WaveHouseClient<DB extends Database = Database> {
723
798
  * `service` role). The endpoint proxies straight to ClickHouse's HTTP
724
799
  * interface so any ClickHouse-accepted SQL works; positional `?` param
725
800
  * binding is NOT supported — inline literals or use the structured query
726
- * builder for safe binding. See sql.ts for details.
801
+ * builder for safe binding. See sql.ts for details. `opts.tenant` names the
802
+ * tenant whose ClickHouse the SQL runs against, the default tenant without
803
+ * it.
727
804
  */
728
- sql<Row = Record<string, unknown>>(query: string, opts?: {
729
- signal?: AbortSignal;
730
- }): Promise<Result<Row[]>>;
805
+ sql<Row = Record<string, unknown>>(query: string, opts?: OpsRequestOptions): Promise<Result<Row[]>>;
731
806
  /** @internal Create a stream for the given table. */
732
807
  private _createStream;
733
808
  }
734
809
  /** Create a new WaveHouse client instance. */
735
810
  declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
736
811
 
737
- export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchLike, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, type PipeRequestOptions, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type RequestOptions, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
812
+ export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchLike, type FilterOp, type InsertPermissions, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OpsRequestOptions, type OrderClause, type ParamDef, type Pipe, PipeRef, type PipeRequestOptions, PipesNamespace, type Policy, type PolicyFilter, QueryBuilder, type QueryFilter, type RequestOptions, type Result, type RolePermissions, SchemaNamespace, type Schemas, type SelectPermissions, type SettingsFinding, SettingsNamespace, type SettingsReloadResult, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, WaveHouseClient, type WaveHouseError, createClient };
package/dist/index.d.ts CHANGED
@@ -241,7 +241,22 @@ interface Column {
241
241
  name: string;
242
242
  type: string;
243
243
  is_nullable: boolean;
244
+ /** Whether the column declares any default at all — see `default_kind`. */
244
245
  has_default: boolean;
246
+ /**
247
+ * How the default is declared, when there is one: `DEFAULT`, `MATERIALIZED`,
248
+ * `ALIAS` or `EPHEMERAL`. Omitted when the column declares none.
249
+ *
250
+ * `MATERIALIZED` and `ALIAS` columns are computed by ClickHouse and cannot be
251
+ * inserted — a record naming one is rejected — so they never appear in an
252
+ * ingest envelope or an SSE `schema` frame, though they are still reported
253
+ * here and are still queryable.
254
+ */
255
+ default_kind?: string;
256
+ /** 1-based ordinal in the table's declaration order — the order `columns` itself is in. Always present. */
257
+ position: number;
258
+ /** The column's DEFAULT expression, absent when it declares none. */
259
+ default_expression?: string;
245
260
  }
246
261
  interface TableSchema {
247
262
  name: string;
@@ -298,17 +313,24 @@ interface ParamDef {
298
313
  }
299
314
  interface Policy {
300
315
  default_role?: string;
316
+ admin_role?: string;
301
317
  tables: Record<string, TablePolicy>;
302
318
  }
303
- interface TablePolicy {
304
- select?: Record<string, RolePermissions>;
305
- insert?: Record<string, RolePermissions>;
306
- }
319
+ /**
320
+ * Access control for one table, keyed by role name. A role appears once per
321
+ * table and states what it may do; omit `select` to deny reads, omit `insert`
322
+ * to deny writes.
323
+ */
324
+ type TablePolicy = Record<string, RolePermissions>;
307
325
  interface RolePermissions {
326
+ select?: SelectPermissions;
327
+ insert?: InsertPermissions;
328
+ }
329
+ /** A role's read grant on a table. */
330
+ interface SelectPermissions {
308
331
  allow_columns?: string[];
309
332
  deny_columns?: string[];
310
333
  filter?: Record<string, PolicyFilter>;
311
- check?: Record<string, PolicyFilter>;
312
334
  allowed_aggregations?: string[];
313
335
  denied_aggregations?: string[];
314
336
  /** Caps the query result LIMIT. 0 = no limit. */
@@ -328,6 +350,12 @@ interface RolePermissions {
328
350
  */
329
351
  max_memory_usage?: number | string;
330
352
  }
353
+ /** A role's write grant on a table. */
354
+ interface InsertPermissions {
355
+ allow_columns?: string[];
356
+ deny_columns?: string[];
357
+ check?: Record<string, PolicyFilter>;
358
+ }
331
359
  interface PolicyFilter {
332
360
  _eq?: string;
333
361
  _neq?: string;
@@ -335,8 +363,31 @@ interface PolicyFilter {
335
363
  _lt?: string;
336
364
  _in?: string;
337
365
  }
338
- interface ValidationResult {
339
- valid: boolean;
366
+ /** One validation finding from the server's settings directory. */
367
+ interface SettingsFinding {
368
+ severity: "error" | "warning";
369
+ /**
370
+ * Settings file the finding is about; absent for directory-level findings.
371
+ * In a directory of tenant folders it leads with the folder
372
+ * (`acme/policies.json`).
373
+ */
374
+ file?: string;
375
+ /** Dotted JSON path within the file; absent for whole-file findings. */
376
+ path?: string;
377
+ message: string;
378
+ }
379
+ /** Body of POST /v1/ops/settings/reload. */
380
+ interface SettingsReloadResult {
381
+ /**
382
+ * Whether everything the reload covered was adopted; false leaves the
383
+ * previous settings in effect. Over a directory of tenant folders false can
384
+ * mean adopted in part: the tenants with an error among their `findings`
385
+ * were not adopted and are no longer served, and the rest were — `findings`
386
+ * carries every folder's warnings too.
387
+ */
388
+ adopted: boolean;
389
+ /** Every finding from the validation pass (warnings included on success). */
390
+ findings: SettingsFinding[];
340
391
  }
341
392
  /**
342
393
  * Options for a single call, passed to `.fetch()`.
@@ -364,6 +415,24 @@ interface PipeRequestOptions {
364
415
  /** Not supported on pipes — pass `limit` as a pipe parameter instead. */
365
416
  limit?: never;
366
417
  }
418
+ /**
419
+ * Options for a call to one of the admin routes that address a tenant:
420
+ * `wh.pipes.list()`, `wh.pipes.get()`, `wh.settings.reload()`,
421
+ * `wh.schema.list()`, `wh.schema.refresh()`, `wh.from(t).schema()`,
422
+ * `wh.dlq.list()`, `wh.dlq.table()` and `wh.sql()`.
423
+ */
424
+ interface OpsRequestOptions {
425
+ signal?: AbortSignal;
426
+ /**
427
+ * The tenant the call addresses, sent as `?tenant=`. The admin routes ignore
428
+ * the `X-Tenant-ID` header, so `options.headers` cannot select one. Omitted,
429
+ * the reads, the refresh and `sql()` serve the default tenant (`0`) and
430
+ * `reload()` reloads every tenant. An id the server does not accept — the
431
+ * empty string included — is a `400`, never a silent fallback to the
432
+ * default.
433
+ */
434
+ tenant?: string;
435
+ }
367
436
  interface StreamOptions {
368
437
  since?: string;
369
438
  signal?: AbortSignal;
@@ -433,14 +502,13 @@ declare class DLQNamespace {
433
502
  private readonly _ctx;
434
503
  private readonly _createStream;
435
504
  constructor(ctx: HttpContext, createStream: CreateStreamFn$3);
436
- /** Get DLQ statistics (message counts per table). */
437
- list(opts?: {
438
- signal?: AbortSignal;
439
- }): Promise<Result<DLQStats>>;
440
- /** Get DLQ stats filtered by table name. */
441
- table(name: string, opts?: {
442
- signal?: AbortSignal;
443
- }): Promise<Result<DLQStats>>;
505
+ /**
506
+ * Get DLQ statistics (message counts per table) — of `opts.tenant`, the
507
+ * default tenant without it. A tenant with no dead-letter queue is a `404`.
508
+ */
509
+ list(opts?: OpsRequestOptions): Promise<Result<DLQStats>>;
510
+ /** Get DLQ stats filtered by table name — of `opts.tenant`, the default tenant without it. */
511
+ table(name: string, opts?: OpsRequestOptions): Promise<Result<DLQStats>>;
444
512
  /** Subscribe to live DLQ events. */
445
513
  stream(opts?: StreamOptions): StreamController;
446
514
  }
@@ -466,58 +534,63 @@ declare class PipeRef<Row = Record<string, unknown>> implements PromiseLike<Resu
466
534
  stream(opts?: StreamOptions): StreamController<Row>;
467
535
  then<TResult1 = Result<Row[]>, TResult2 = never>(onfulfilled?: ((value: Result<Row[]>) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
468
536
  }
469
- /** Admin namespace for managing named query pipes. */
537
+ /**
538
+ * Admin namespace for reading named query pipes.
539
+ *
540
+ * Pipes are defined in the server's settings directory (`pipes.json`, with
541
+ * every `allowed_roles` entry declared in `roles.json`); the files are the only
542
+ * way to define or change a pipe. Edit the files and the server re-adopts them on change, on
543
+ * SIGHUP, or on `wh.settings.reload()` (POST /v1/ops/settings/reload).
544
+ */
470
545
  declare class PipesNamespace {
471
546
  private readonly _ctx;
472
547
  constructor(ctx: HttpContext);
473
- /** List all registered pipes. */
474
- list(opts?: {
475
- signal?: AbortSignal;
476
- }): Promise<Result<Pipe[]>>;
477
- /** Get a single pipe definition by name. */
478
- get(name: string, opts?: {
479
- signal?: AbortSignal;
480
- }): Promise<Result<Pipe>>;
481
- /** Create or update a pipe. */
482
- set(name: string, def: Omit<Pipe, "name">, opts?: {
483
- signal?: AbortSignal;
484
- }): Promise<Result<void>>;
485
- /** Delete a pipe by name. */
486
- delete(name: string, opts?: {
487
- signal?: AbortSignal;
488
- }): Promise<Result<void>>;
548
+ /** List all registered pipes — of `opts.tenant`, the default tenant without it. */
549
+ list(opts?: OpsRequestOptions): Promise<Result<Pipe[]>>;
550
+ /** Get a single pipe definition by name — of `opts.tenant`, the default tenant without it. */
551
+ get(name: string, opts?: OpsRequestOptions): Promise<Result<Pipe>>;
489
552
  }
490
553
 
491
- /** Namespace for access control policy management. Requires the admin role (the configured `admin_role`, `"admin"` by default). */
492
- declare class PolicyNamespace {
554
+ /** Namespace for schema introspection. */
555
+ declare class SchemaNamespace {
493
556
  private readonly _ctx;
494
557
  constructor(ctx: HttpContext);
495
- /** Get the current access control policy. */
496
- get(opts?: {
497
- signal?: AbortSignal;
498
- }): Promise<Result<Policy>>;
499
- /** Replace the entire access control policy. */
500
- set(policy: Policy, opts?: {
501
- signal?: AbortSignal;
502
- }): Promise<Result<void>>;
503
- /** Validate a policy without applying it (dry run). */
504
- validate(policy: Policy, opts?: {
505
- signal?: AbortSignal;
506
- }): Promise<Result<ValidationResult>>;
558
+ /**
559
+ * List all table schemas discovered from ClickHouse — `opts.tenant`'s, the
560
+ * default tenant's without it. A `503` with `Retry-After` is a tenant whose
561
+ * first discovery has not succeeded yet.
562
+ */
563
+ list(opts?: OpsRequestOptions): Promise<Result<Schemas>>;
564
+ /**
565
+ * Force a schema refresh from ClickHouse system.columns — of `opts.tenant`,
566
+ * the default tenant without it.
567
+ */
568
+ refresh(opts?: OpsRequestOptions): Promise<Result<void>>;
507
569
  }
508
570
 
509
- /** Namespace for schema introspection. */
510
- declare class SchemaNamespace {
571
+ /**
572
+ * Namespace for the server's hot-reloadable settings directory. Requires the
573
+ * admin role (the configured `admin_role`, `"admin"` by default).
574
+ *
575
+ * Policy (`policies.json`), roles (`roles.json`), and pipes (`pipes.json`)
576
+ * are defined in that directory; files are the only write path. The server
577
+ * re-adopts them on file change and on SIGHUP, and `reload()` triggers the
578
+ * same path on demand.
579
+ */
580
+ declare class SettingsNamespace {
511
581
  private readonly _ctx;
512
582
  constructor(ctx: HttpContext);
513
- /** List all table schemas discovered from ClickHouse. */
514
- list(opts?: {
515
- signal?: AbortSignal;
516
- }): Promise<Result<Schemas>>;
517
- /** Force a schema refresh from ClickHouse system.columns. */
518
- refresh(opts?: {
519
- signal?: AbortSignal;
520
- }): Promise<Result<void>>;
583
+ /**
584
+ * Re-validate and adopt the settings directory (POST /v1/ops/settings/reload).
585
+ * Resolves with `{ adopted: true, findings }` when adopted (warnings
586
+ * included); a rejected directory is a 422 error whose `details` carries the
587
+ * same `{ adopted: false, findings }` body, and the previous settings stay
588
+ * in effect.
589
+ *
590
+ * `opts.tenant` reloads that tenant's folder alone; without it the whole
591
+ * directory is reloaded.
592
+ */
593
+ reload(opts?: OpsRequestOptions): Promise<Result<SettingsReloadResult>>;
521
594
  }
522
595
 
523
596
  /** Namespace for the SDK's content-free server-online check. */
@@ -662,8 +735,10 @@ declare class TableRef<Row = Record<string, unknown>> {
662
735
  * rest of the batch — per-record outcomes come back in the result
663
736
  * (`failed` / `results`), and `ok` is true only when every record succeeded.
664
737
  *
665
- * The array path sends one request regardless of size; bounded-concurrency
666
- * chunking of very large arrays is tracked separately (#196). For NDJSON you
738
+ * The array path sends one request regardless of size, so it is bound by the
739
+ * server's 16 MiB request-body cap (an over-cap array is a `413` with nothing
740
+ * ingested); bounded-concurrency chunking of very large arrays is tracked
741
+ * separately (#196). For NDJSON you
667
742
  * already have (a file or stream), use {@link insertNDJSON}.
668
743
  */
669
744
  insert(data: Partial<Row> | Partial<Row>[], opts?: {
@@ -675,9 +750,11 @@ declare class TableRef<Row = Record<string, unknown>> {
675
750
  * file or a stream produced by another system. For in-memory rows, prefer
676
751
  * {@link insert}.
677
752
  *
678
- * Non-string sources are read fully into memory before sending (the server
679
- * streams the parse). Returns the same per-record batch summary as an array
680
- * `insert`.
753
+ * Non-string sources are read fully into memory before sending. The server
754
+ * buffers the whole body too, so the request-body cap applies to NDJSON
755
+ * exactly as to any other shape — an upload over it is a `413` with nothing
756
+ * ingested, and must be split across several calls. Returns the same
757
+ * per-record batch summary as an array `insert`.
681
758
  */
682
759
  insertNDJSON(source: NDJSONSource, opts?: {
683
760
  signal?: AbortSignal;
@@ -689,10 +766,8 @@ declare class TableRef<Row = Record<string, unknown>> {
689
766
  * as the success arm with `ok = failed === 0`.
690
767
  */
691
768
  private _sendNDJSON;
692
- /** Fetch the schema for this table. */
693
- schema(opts?: {
694
- signal?: AbortSignal;
695
- }): Promise<Result<TableSchema>>;
769
+ /** Fetch the schema for this table — under `opts.tenant`, the default tenant without it. */
770
+ schema(opts?: OpsRequestOptions): Promise<Result<TableSchema>>;
696
771
  /** Subscribe to live events for this table. */
697
772
  stream(opts?: StreamOptions): StreamController<Row>;
698
773
  }
@@ -704,14 +779,14 @@ declare class WaveHouseClient<DB extends Database = Database> {
704
779
  readonly _ctx: HttpContext;
705
780
  /** Schema introspection namespace. */
706
781
  readonly schema: SchemaNamespace;
707
- /** Access control policy namespace (admin). */
708
- readonly policy: PolicyNamespace;
709
782
  /** Dead Letter Queue namespace. */
710
783
  readonly dlq: DLQNamespace;
711
784
  /** System health/readiness namespace. */
712
785
  readonly sys: SysNamespace;
713
786
  /** Named query pipes admin namespace. */
714
787
  readonly pipes: PipesNamespace;
788
+ /** Settings directory namespace (admin). */
789
+ readonly settings: SettingsNamespace;
715
790
  constructor(config: ClientConfig<DB>);
716
791
  /** Get a table reference for building queries, inserts, and streams. */
717
792
  from<T extends TableName<DB>>(table: T): TableRef<RowType<DB, T>>;
@@ -723,15 +798,15 @@ declare class WaveHouseClient<DB extends Database = Database> {
723
798
  * `service` role). The endpoint proxies straight to ClickHouse's HTTP
724
799
  * interface so any ClickHouse-accepted SQL works; positional `?` param
725
800
  * binding is NOT supported — inline literals or use the structured query
726
- * builder for safe binding. See sql.ts for details.
801
+ * builder for safe binding. See sql.ts for details. `opts.tenant` names the
802
+ * tenant whose ClickHouse the SQL runs against, the default tenant without
803
+ * it.
727
804
  */
728
- sql<Row = Record<string, unknown>>(query: string, opts?: {
729
- signal?: AbortSignal;
730
- }): Promise<Result<Row[]>>;
805
+ sql<Row = Record<string, unknown>>(query: string, opts?: OpsRequestOptions): Promise<Result<Row[]>>;
731
806
  /** @internal Create a stream for the given table. */
732
807
  private _createStream;
733
808
  }
734
809
  /** Create a new WaveHouse client instance. */
735
810
  declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
736
811
 
737
- export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchLike, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, type PipeRequestOptions, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, type RequestOptions, type Result, type RolePermissions, SchemaNamespace, type Schemas, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, type ValidationResult, WaveHouseClient, type WaveHouseError, createClient };
812
+ export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchLike, type FilterOp, type InsertPermissions, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OpsRequestOptions, type OrderClause, type ParamDef, type Pipe, PipeRef, type PipeRequestOptions, PipesNamespace, type Policy, type PolicyFilter, QueryBuilder, type QueryFilter, type RequestOptions, type Result, type RolePermissions, SchemaNamespace, type Schemas, type SelectPermissions, type SettingsFinding, SettingsNamespace, type SettingsReloadResult, StreamController, type StreamEvent, type StreamOptions, type StreamStatus, type StreamSubscriber, type StructuredQuery, SysNamespace, type TablePolicy, TableRef, type TableSchema, type TimeRange, WaveHouseClient, type WaveHouseError, createClient };