@wavehouse/sdk 0.0.0-dev.h825a5d7fa405 → 0.0.0-dev.hab0797ca5a74
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.cjs +93 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -2
- package/dist/index.d.ts +93 -2
- package/dist/index.js +93 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -59,7 +59,19 @@ interface ClientOptions {
|
|
|
59
59
|
maxRetries?: number;
|
|
60
60
|
}
|
|
61
61
|
interface StructuredQuery {
|
|
62
|
+
/**
|
|
63
|
+
* Explicit columns to project. A literal "*" is a column named "*", not a
|
|
64
|
+
* wildcard. Omitting columns (with no aggregations and no select_all) selects
|
|
65
|
+
* nothing — use select_all for a full-row read. Mutually exclusive with
|
|
66
|
+
* select_all.
|
|
67
|
+
*/
|
|
62
68
|
columns?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Request every column the caller's role may read (the all-columns wildcard,
|
|
71
|
+
* expanded server-side to the allowed/denied set). Mutually exclusive with a
|
|
72
|
+
* non-empty columns list.
|
|
73
|
+
*/
|
|
74
|
+
select_all?: boolean;
|
|
63
75
|
aggregations?: Aggregation[];
|
|
64
76
|
filters?: QueryFilter[];
|
|
65
77
|
group_by?: string[];
|
|
@@ -97,9 +109,36 @@ interface TableSchema {
|
|
|
97
109
|
columns: Column[];
|
|
98
110
|
}
|
|
99
111
|
type Schemas = Record<string, TableSchema>;
|
|
112
|
+
/**
|
|
113
|
+
* A per-record outcome from a batch (array / NDJSON) insert. Mirrors the
|
|
114
|
+
* single-object response shape plus the record's position. Exactly one of
|
|
115
|
+
* `ok` / `duplicate` / `error` is set.
|
|
116
|
+
*/
|
|
117
|
+
interface InsertRecordResult {
|
|
118
|
+
/** 1-based index of the record within the submitted batch. */
|
|
119
|
+
index: number;
|
|
120
|
+
/** Set when the record was validated and published. */
|
|
121
|
+
ok?: boolean;
|
|
122
|
+
/** Set when dedup skipped the record. */
|
|
123
|
+
duplicate?: boolean;
|
|
124
|
+
/** Set (with `ok`/`duplicate` absent) when the record was rejected. */
|
|
125
|
+
error?: string;
|
|
126
|
+
}
|
|
100
127
|
interface InsertResult {
|
|
128
|
+
/** True for a fully successful insert: a single row, or a batch with no rejected records (`failed === 0`). */
|
|
101
129
|
ok: boolean;
|
|
130
|
+
/** Single insert only: set when dedup skipped the row. */
|
|
102
131
|
duplicate?: boolean;
|
|
132
|
+
/** Batch insert (array / NDJSON): number of records submitted. */
|
|
133
|
+
total?: number;
|
|
134
|
+
/** Batch insert: records validated and published. */
|
|
135
|
+
succeeded?: number;
|
|
136
|
+
/** Batch insert: records rejected — see `results`. */
|
|
137
|
+
failed?: number;
|
|
138
|
+
/** Batch insert: records skipped by dedup. */
|
|
139
|
+
duplicates?: number;
|
|
140
|
+
/** Batch insert: per-record outcomes, each `{index, ok|duplicate|error}` (may be truncated for very large batches; the counts stay authoritative). */
|
|
141
|
+
results?: InsertRecordResult[];
|
|
103
142
|
}
|
|
104
143
|
interface DLQStats {
|
|
105
144
|
tables: Record<string, number>;
|
|
@@ -339,6 +378,7 @@ declare class LiveQuery<T = Record<string, unknown>> {
|
|
|
339
378
|
interface QueryState {
|
|
340
379
|
table: string;
|
|
341
380
|
columns: string[];
|
|
381
|
+
selectAll?: boolean;
|
|
342
382
|
aggregations: Aggregation[];
|
|
343
383
|
filters: QueryFilter[];
|
|
344
384
|
groupBy: string[];
|
|
@@ -361,6 +401,13 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
361
401
|
private readonly _createStream;
|
|
362
402
|
constructor(ctx: HttpContext, state: QueryState, createStream: CreateStreamFn$1<Row>);
|
|
363
403
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
404
|
+
/**
|
|
405
|
+
* Select every column the caller's role is allowed to read (the all-columns
|
|
406
|
+
* wildcard). Use this instead of `.select(...)` when you want a full-row read;
|
|
407
|
+
* a bare `.fetch()` with no `.select()` does this implicitly. Mutually
|
|
408
|
+
* exclusive with `.select(...)`.
|
|
409
|
+
*/
|
|
410
|
+
selectAll(): QueryBuilder<Row>;
|
|
364
411
|
where(column: string, op: FilterOp, value: unknown): QueryBuilder<Row>;
|
|
365
412
|
count(column?: string, alias?: string): QueryBuilder<Row>;
|
|
366
413
|
sum(column: string, alias?: string): QueryBuilder<Row>;
|
|
@@ -396,6 +443,12 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
396
443
|
}
|
|
397
444
|
|
|
398
445
|
type CreateStreamFn<Row> = (table: string, opts?: StreamOptions) => StreamController<Row>;
|
|
446
|
+
/**
|
|
447
|
+
* Accepted sources for {@link TableRef.insertNDJSON}: a string, raw bytes, a
|
|
448
|
+
* Blob/File (browser file inputs), or a byte stream. Non-string sources are
|
|
449
|
+
* read fully before sending.
|
|
450
|
+
*/
|
|
451
|
+
type NDJSONSource = string | Uint8Array | Blob | ReadableStream<Uint8Array>;
|
|
399
452
|
/**
|
|
400
453
|
* Reference to a table. NOT thenable — safe to pass around without triggering requests.
|
|
401
454
|
* Use `.fetch()`, `.select()`, `.insert()`, `.schema()`, or `.stream()` to act on it.
|
|
@@ -409,10 +462,48 @@ declare class TableRef<Row = Record<string, unknown>> {
|
|
|
409
462
|
fetch(opts?: FetchOptions): Promise<Result<Row[]>>;
|
|
410
463
|
/** Start building a typed query. Returns an immutable, PromiseLike QueryBuilder. */
|
|
411
464
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
412
|
-
/**
|
|
465
|
+
/**
|
|
466
|
+
* Start a query that selects every column the caller's role is allowed to read
|
|
467
|
+
* (the all-columns wildcard). Use instead of `.select(...)` for an explicit
|
|
468
|
+
* full-row read; `.fetch()` does this implicitly.
|
|
469
|
+
*/
|
|
470
|
+
selectAll(): QueryBuilder<Row>;
|
|
471
|
+
/**
|
|
472
|
+
* Insert one or more rows into this table.
|
|
473
|
+
*
|
|
474
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
475
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
476
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
477
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
478
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
479
|
+
*
|
|
480
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
481
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
482
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
483
|
+
*/
|
|
413
484
|
insert(data: Partial<Row> | Partial<Row>[], opts?: {
|
|
414
485
|
signal?: AbortSignal;
|
|
415
486
|
}): Promise<Result<InsertResult>>;
|
|
487
|
+
/**
|
|
488
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
489
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
490
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
491
|
+
* {@link insert}.
|
|
492
|
+
*
|
|
493
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
494
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
495
|
+
* `insert`.
|
|
496
|
+
*/
|
|
497
|
+
insertNDJSON(source: NDJSONSource, opts?: {
|
|
498
|
+
signal?: AbortSignal;
|
|
499
|
+
}): Promise<Result<InsertResult>>;
|
|
500
|
+
/**
|
|
501
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
502
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
503
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
504
|
+
* as the success arm with `ok = failed === 0`.
|
|
505
|
+
*/
|
|
506
|
+
private _sendNDJSON;
|
|
416
507
|
/** Fetch the schema for this table. */
|
|
417
508
|
schema(opts?: {
|
|
418
509
|
signal?: AbortSignal;
|
|
@@ -458,4 +549,4 @@ declare class WaveHouseClient<DB extends Database = Database> {
|
|
|
458
549
|
/** Create a new WaveHouse client instance. */
|
|
459
550
|
declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
|
|
460
551
|
|
|
461
|
-
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertResult, LiveQuery, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, 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 };
|
|
552
|
+
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -59,7 +59,19 @@ interface ClientOptions {
|
|
|
59
59
|
maxRetries?: number;
|
|
60
60
|
}
|
|
61
61
|
interface StructuredQuery {
|
|
62
|
+
/**
|
|
63
|
+
* Explicit columns to project. A literal "*" is a column named "*", not a
|
|
64
|
+
* wildcard. Omitting columns (with no aggregations and no select_all) selects
|
|
65
|
+
* nothing — use select_all for a full-row read. Mutually exclusive with
|
|
66
|
+
* select_all.
|
|
67
|
+
*/
|
|
62
68
|
columns?: string[];
|
|
69
|
+
/**
|
|
70
|
+
* Request every column the caller's role may read (the all-columns wildcard,
|
|
71
|
+
* expanded server-side to the allowed/denied set). Mutually exclusive with a
|
|
72
|
+
* non-empty columns list.
|
|
73
|
+
*/
|
|
74
|
+
select_all?: boolean;
|
|
63
75
|
aggregations?: Aggregation[];
|
|
64
76
|
filters?: QueryFilter[];
|
|
65
77
|
group_by?: string[];
|
|
@@ -97,9 +109,36 @@ interface TableSchema {
|
|
|
97
109
|
columns: Column[];
|
|
98
110
|
}
|
|
99
111
|
type Schemas = Record<string, TableSchema>;
|
|
112
|
+
/**
|
|
113
|
+
* A per-record outcome from a batch (array / NDJSON) insert. Mirrors the
|
|
114
|
+
* single-object response shape plus the record's position. Exactly one of
|
|
115
|
+
* `ok` / `duplicate` / `error` is set.
|
|
116
|
+
*/
|
|
117
|
+
interface InsertRecordResult {
|
|
118
|
+
/** 1-based index of the record within the submitted batch. */
|
|
119
|
+
index: number;
|
|
120
|
+
/** Set when the record was validated and published. */
|
|
121
|
+
ok?: boolean;
|
|
122
|
+
/** Set when dedup skipped the record. */
|
|
123
|
+
duplicate?: boolean;
|
|
124
|
+
/** Set (with `ok`/`duplicate` absent) when the record was rejected. */
|
|
125
|
+
error?: string;
|
|
126
|
+
}
|
|
100
127
|
interface InsertResult {
|
|
128
|
+
/** True for a fully successful insert: a single row, or a batch with no rejected records (`failed === 0`). */
|
|
101
129
|
ok: boolean;
|
|
130
|
+
/** Single insert only: set when dedup skipped the row. */
|
|
102
131
|
duplicate?: boolean;
|
|
132
|
+
/** Batch insert (array / NDJSON): number of records submitted. */
|
|
133
|
+
total?: number;
|
|
134
|
+
/** Batch insert: records validated and published. */
|
|
135
|
+
succeeded?: number;
|
|
136
|
+
/** Batch insert: records rejected — see `results`. */
|
|
137
|
+
failed?: number;
|
|
138
|
+
/** Batch insert: records skipped by dedup. */
|
|
139
|
+
duplicates?: number;
|
|
140
|
+
/** Batch insert: per-record outcomes, each `{index, ok|duplicate|error}` (may be truncated for very large batches; the counts stay authoritative). */
|
|
141
|
+
results?: InsertRecordResult[];
|
|
103
142
|
}
|
|
104
143
|
interface DLQStats {
|
|
105
144
|
tables: Record<string, number>;
|
|
@@ -339,6 +378,7 @@ declare class LiveQuery<T = Record<string, unknown>> {
|
|
|
339
378
|
interface QueryState {
|
|
340
379
|
table: string;
|
|
341
380
|
columns: string[];
|
|
381
|
+
selectAll?: boolean;
|
|
342
382
|
aggregations: Aggregation[];
|
|
343
383
|
filters: QueryFilter[];
|
|
344
384
|
groupBy: string[];
|
|
@@ -361,6 +401,13 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
361
401
|
private readonly _createStream;
|
|
362
402
|
constructor(ctx: HttpContext, state: QueryState, createStream: CreateStreamFn$1<Row>);
|
|
363
403
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
404
|
+
/**
|
|
405
|
+
* Select every column the caller's role is allowed to read (the all-columns
|
|
406
|
+
* wildcard). Use this instead of `.select(...)` when you want a full-row read;
|
|
407
|
+
* a bare `.fetch()` with no `.select()` does this implicitly. Mutually
|
|
408
|
+
* exclusive with `.select(...)`.
|
|
409
|
+
*/
|
|
410
|
+
selectAll(): QueryBuilder<Row>;
|
|
364
411
|
where(column: string, op: FilterOp, value: unknown): QueryBuilder<Row>;
|
|
365
412
|
count(column?: string, alias?: string): QueryBuilder<Row>;
|
|
366
413
|
sum(column: string, alias?: string): QueryBuilder<Row>;
|
|
@@ -396,6 +443,12 @@ declare class QueryBuilder<Row = Record<string, unknown>> implements PromiseLike
|
|
|
396
443
|
}
|
|
397
444
|
|
|
398
445
|
type CreateStreamFn<Row> = (table: string, opts?: StreamOptions) => StreamController<Row>;
|
|
446
|
+
/**
|
|
447
|
+
* Accepted sources for {@link TableRef.insertNDJSON}: a string, raw bytes, a
|
|
448
|
+
* Blob/File (browser file inputs), or a byte stream. Non-string sources are
|
|
449
|
+
* read fully before sending.
|
|
450
|
+
*/
|
|
451
|
+
type NDJSONSource = string | Uint8Array | Blob | ReadableStream<Uint8Array>;
|
|
399
452
|
/**
|
|
400
453
|
* Reference to a table. NOT thenable — safe to pass around without triggering requests.
|
|
401
454
|
* Use `.fetch()`, `.select()`, `.insert()`, `.schema()`, or `.stream()` to act on it.
|
|
@@ -409,10 +462,48 @@ declare class TableRef<Row = Record<string, unknown>> {
|
|
|
409
462
|
fetch(opts?: FetchOptions): Promise<Result<Row[]>>;
|
|
410
463
|
/** Start building a typed query. Returns an immutable, PromiseLike QueryBuilder. */
|
|
411
464
|
select(...columns: string[]): QueryBuilder<Row>;
|
|
412
|
-
/**
|
|
465
|
+
/**
|
|
466
|
+
* Start a query that selects every column the caller's role is allowed to read
|
|
467
|
+
* (the all-columns wildcard). Use instead of `.select(...)` for an explicit
|
|
468
|
+
* full-row read; `.fetch()` does this implicitly.
|
|
469
|
+
*/
|
|
470
|
+
selectAll(): QueryBuilder<Row>;
|
|
471
|
+
/**
|
|
472
|
+
* Insert one or more rows into this table.
|
|
473
|
+
*
|
|
474
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
475
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
476
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
477
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
478
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
479
|
+
*
|
|
480
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
481
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
482
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
483
|
+
*/
|
|
413
484
|
insert(data: Partial<Row> | Partial<Row>[], opts?: {
|
|
414
485
|
signal?: AbortSignal;
|
|
415
486
|
}): Promise<Result<InsertResult>>;
|
|
487
|
+
/**
|
|
488
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
489
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
490
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
491
|
+
* {@link insert}.
|
|
492
|
+
*
|
|
493
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
494
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
495
|
+
* `insert`.
|
|
496
|
+
*/
|
|
497
|
+
insertNDJSON(source: NDJSONSource, opts?: {
|
|
498
|
+
signal?: AbortSignal;
|
|
499
|
+
}): Promise<Result<InsertResult>>;
|
|
500
|
+
/**
|
|
501
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
502
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
503
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
504
|
+
* as the success arm with `ok = failed === 0`.
|
|
505
|
+
*/
|
|
506
|
+
private _sendNDJSON;
|
|
416
507
|
/** Fetch the schema for this table. */
|
|
417
508
|
schema(opts?: {
|
|
418
509
|
signal?: AbortSignal;
|
|
@@ -458,4 +549,4 @@ declare class WaveHouseClient<DB extends Database = Database> {
|
|
|
458
549
|
/** Create a new WaveHouse client instance. */
|
|
459
550
|
declare function createClient<DB extends Database = Database>(config: ClientConfig<DB>): WaveHouseClient<DB>;
|
|
460
551
|
|
|
461
|
-
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertResult, LiveQuery, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, 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 };
|
|
552
|
+
export { type Aggregation, type ClientConfig, type ClientOptions, type Column, DLQNamespace, type DLQStats, type Database, type FetchOptions, type FilterOp, type InsertRecordResult, type InsertResult, LiveQuery, type NDJSONSource, type OrderClause, type ParamDef, type Pipe, PipeRef, PipesNamespace, type Policy, type PolicyFilter, PolicyNamespace, QueryBuilder, type QueryFilter, 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 };
|
package/dist/index.js
CHANGED
|
@@ -39,9 +39,10 @@ function err(error) {
|
|
|
39
39
|
async function request(ctx, opts) {
|
|
40
40
|
const url = buildURL(ctx.baseURL, opts.path, opts.params);
|
|
41
41
|
const headers = {
|
|
42
|
-
"Content-Type": "application/json",
|
|
42
|
+
"Content-Type": opts.contentType ?? "application/json",
|
|
43
43
|
Accept: "application/json"
|
|
44
44
|
};
|
|
45
|
+
const requestBody = opts.rawBody !== void 0 ? opts.rawBody : opts.body !== void 0 ? JSON.stringify(opts.body) : void 0;
|
|
45
46
|
if (ctx.auth) {
|
|
46
47
|
const token = await ctx.auth();
|
|
47
48
|
if (token) {
|
|
@@ -55,7 +56,7 @@ async function request(ctx, opts) {
|
|
|
55
56
|
const res = await fetch(url, {
|
|
56
57
|
method: opts.method,
|
|
57
58
|
headers,
|
|
58
|
-
body:
|
|
59
|
+
body: requestBody,
|
|
59
60
|
signal: opts.signal
|
|
60
61
|
});
|
|
61
62
|
if (res.ok) {
|
|
@@ -690,6 +691,15 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
690
691
|
select(...columns) {
|
|
691
692
|
return this._clone({ columns: [...this._state.columns, ...columns] });
|
|
692
693
|
}
|
|
694
|
+
/**
|
|
695
|
+
* Select every column the caller's role is allowed to read (the all-columns
|
|
696
|
+
* wildcard). Use this instead of `.select(...)` when you want a full-row read;
|
|
697
|
+
* a bare `.fetch()` with no `.select()` does this implicitly. Mutually
|
|
698
|
+
* exclusive with `.select(...)`.
|
|
699
|
+
*/
|
|
700
|
+
selectAll() {
|
|
701
|
+
return this._clone({ selectAll: true });
|
|
702
|
+
}
|
|
693
703
|
where(column, op, value) {
|
|
694
704
|
const filter = { column, op: OP_MAP[op], value };
|
|
695
705
|
return this._clone({ filters: [...this._state.filters, filter] });
|
|
@@ -788,8 +798,16 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
788
798
|
}
|
|
789
799
|
_buildAST(effectiveLimit) {
|
|
790
800
|
const ast = {};
|
|
791
|
-
|
|
792
|
-
|
|
801
|
+
const hasColumns = this._state.columns.length > 0;
|
|
802
|
+
const hasAggs = this._state.aggregations.length > 0;
|
|
803
|
+
if (this._state.selectAll) {
|
|
804
|
+
ast.select_all = true;
|
|
805
|
+
} else if (hasColumns) {
|
|
806
|
+
ast.columns = this._state.columns;
|
|
807
|
+
} else if (!hasAggs) {
|
|
808
|
+
ast.select_all = true;
|
|
809
|
+
}
|
|
810
|
+
if (hasAggs) ast.aggregations = this._state.aggregations;
|
|
793
811
|
if (this._state.filters.length > 0) ast.filters = this._state.filters;
|
|
794
812
|
if (this._state.groupBy.length > 0) ast.group_by = this._state.groupBy;
|
|
795
813
|
if (this._state.orderBy.length > 0) ast.order_by = this._state.orderBy;
|
|
@@ -899,6 +917,12 @@ function projectColumns(row, columns) {
|
|
|
899
917
|
}
|
|
900
918
|
|
|
901
919
|
// src/table.ts
|
|
920
|
+
var NDJSON_CONTENT_TYPE = "application/x-ndjson";
|
|
921
|
+
async function ndjsonSourceToString(source) {
|
|
922
|
+
if (typeof source === "string") return source;
|
|
923
|
+
if (source instanceof Uint8Array) return new TextDecoder().decode(source);
|
|
924
|
+
return new Response(source).text();
|
|
925
|
+
}
|
|
902
926
|
var TableRef = class {
|
|
903
927
|
_ctx;
|
|
904
928
|
_table;
|
|
@@ -927,22 +951,34 @@ var TableRef = class {
|
|
|
927
951
|
this._createStream
|
|
928
952
|
);
|
|
929
953
|
}
|
|
930
|
-
/**
|
|
954
|
+
/**
|
|
955
|
+
* Start a query that selects every column the caller's role is allowed to read
|
|
956
|
+
* (the all-columns wildcard). Use instead of `.select(...)` for an explicit
|
|
957
|
+
* full-row read; `.fetch()` does this implicitly.
|
|
958
|
+
*/
|
|
959
|
+
selectAll() {
|
|
960
|
+
return this.select().selectAll();
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Insert one or more rows into this table.
|
|
964
|
+
*
|
|
965
|
+
* A single object is sent as a JSON `POST /v1/ingest`. An **array** is
|
|
966
|
+
* serialized to NDJSON (one record per line) and sent as a single
|
|
967
|
+
* `application/x-ndjson` request: a bad record no longer fails or hides the
|
|
968
|
+
* rest of the batch — per-record outcomes come back in the result
|
|
969
|
+
* (`failed` / `results`), and `ok` is true only when every record succeeded.
|
|
970
|
+
*
|
|
971
|
+
* The array path sends one request regardless of size; bounded-concurrency
|
|
972
|
+
* chunking of very large arrays is tracked separately (#196). For NDJSON you
|
|
973
|
+
* already have (a file or stream), use {@link insertNDJSON}.
|
|
974
|
+
*/
|
|
931
975
|
async insert(data, opts) {
|
|
932
976
|
if (Array.isArray(data)) {
|
|
933
|
-
|
|
934
|
-
(
|
|
935
|
-
method: "POST",
|
|
936
|
-
path: `/v1/ingest?table=${encodeURIComponent(this._table)}`,
|
|
937
|
-
body: row,
|
|
938
|
-
signal: opts?.signal
|
|
939
|
-
})
|
|
940
|
-
);
|
|
941
|
-
const results = await Promise.all(promises);
|
|
942
|
-
for (const res2 of results) {
|
|
943
|
-
if (res2.error) return err(res2.error);
|
|
977
|
+
if (data.length === 0) {
|
|
978
|
+
return ok({ ok: true, total: 0, succeeded: 0, failed: 0, duplicates: 0, results: [] });
|
|
944
979
|
}
|
|
945
|
-
|
|
980
|
+
const ndjson = data.map((row) => JSON.stringify(row)).join("\n");
|
|
981
|
+
return this._sendNDJSON(ndjson, opts);
|
|
946
982
|
}
|
|
947
983
|
const { data: res, error } = await request(this._ctx, {
|
|
948
984
|
method: "POST",
|
|
@@ -955,6 +991,46 @@ var TableRef = class {
|
|
|
955
991
|
if (res?.duplicate != null) result.duplicate = res.duplicate;
|
|
956
992
|
return ok(result);
|
|
957
993
|
}
|
|
994
|
+
/**
|
|
995
|
+
* Insert pre-formatted NDJSON (newline-delimited JSON, one record per line)
|
|
996
|
+
* from a string, raw bytes, a Blob/File, or a byte stream — e.g. a `.ndjson`
|
|
997
|
+
* file or a stream produced by another system. For in-memory rows, prefer
|
|
998
|
+
* {@link insert}.
|
|
999
|
+
*
|
|
1000
|
+
* Non-string sources are read fully into memory before sending (the server
|
|
1001
|
+
* streams the parse). Returns the same per-record batch summary as an array
|
|
1002
|
+
* `insert`.
|
|
1003
|
+
*/
|
|
1004
|
+
async insertNDJSON(source, opts) {
|
|
1005
|
+
const ndjson = await ndjsonSourceToString(source);
|
|
1006
|
+
return this._sendNDJSON(ndjson, opts);
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* @internal Send an NDJSON body and map the server's batch response onto an
|
|
1010
|
+
* {@link InsertResult}. A transport / whole-request failure surfaces as the
|
|
1011
|
+
* Result error arm; a processed batch (even with rejected records) surfaces
|
|
1012
|
+
* as the success arm with `ok = failed === 0`.
|
|
1013
|
+
*/
|
|
1014
|
+
async _sendNDJSON(ndjson, opts) {
|
|
1015
|
+
const { data, error } = await request(this._ctx, {
|
|
1016
|
+
method: "POST",
|
|
1017
|
+
path: `/v1/ingest?table=${encodeURIComponent(this._table)}`,
|
|
1018
|
+
rawBody: ndjson,
|
|
1019
|
+
contentType: NDJSON_CONTENT_TYPE,
|
|
1020
|
+
signal: opts?.signal
|
|
1021
|
+
});
|
|
1022
|
+
if (error) return err(error);
|
|
1023
|
+
const r = data ?? { total: 0, succeeded: 0, failed: 0, duplicates: 0 };
|
|
1024
|
+
const result = {
|
|
1025
|
+
ok: r.failed === 0,
|
|
1026
|
+
total: r.total,
|
|
1027
|
+
succeeded: r.succeeded,
|
|
1028
|
+
failed: r.failed,
|
|
1029
|
+
duplicates: r.duplicates
|
|
1030
|
+
};
|
|
1031
|
+
if (r.results && r.results.length > 0) result.results = r.results;
|
|
1032
|
+
return ok(result);
|
|
1033
|
+
}
|
|
958
1034
|
/** Fetch the schema for this table. */
|
|
959
1035
|
async schema(opts) {
|
|
960
1036
|
const { data, error } = await request(this._ctx, {
|