@wavehouse/sdk 0.0.0-dev.h514be5522d89 → 0.0.0-dev.h70dbf5d8f5ed

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.js CHANGED
@@ -35,9 +35,39 @@ function err(error) {
35
35
  return { ok: false, data: null, error };
36
36
  }
37
37
 
38
+ // src/url.ts
39
+ function resolveURL(base, path, params) {
40
+ const root = new URL(base);
41
+ root.search = "";
42
+ root.hash = "";
43
+ if (!root.pathname.endsWith("/")) root.pathname += "/";
44
+ const url = new URL(path.replace(/^\/+/, ""), root);
45
+ if (params) {
46
+ for (const [k, v] of Object.entries(params)) {
47
+ url.searchParams.set(k, v);
48
+ }
49
+ }
50
+ return url;
51
+ }
52
+
38
53
  // src/http.ts
54
+ function mergeHeaders(base, extra) {
55
+ if (!extra) return base;
56
+ const sdkNames = new Set(Object.keys(base).map((k) => k.toLowerCase()));
57
+ const merged = { ...base };
58
+ const configured = /* @__PURE__ */ new Map();
59
+ for (const [name, value] of Object.entries(extra)) {
60
+ const lower = name.toLowerCase();
61
+ if (sdkNames.has(lower)) continue;
62
+ const prior = configured.get(lower);
63
+ if (prior !== void 0) delete merged[prior];
64
+ merged[name] = value;
65
+ configured.set(lower, name);
66
+ }
67
+ return merged;
68
+ }
39
69
  async function request(ctx, opts) {
40
- const url = buildURL(ctx.baseURL, opts.path, opts.params);
70
+ const url = resolveURL(ctx.baseURL, opts.path, opts.params).toString();
41
71
  const headers = {
42
72
  "Content-Type": opts.contentType ?? "application/json",
43
73
  Accept: "application/json"
@@ -49,16 +79,20 @@ async function request(ctx, opts) {
49
79
  headers.Authorization = `Bearer ${token}`;
50
80
  }
51
81
  }
82
+ const finalHeaders = mergeHeaders(headers, ctx.options.headers);
52
83
  let lastError = null;
53
84
  const maxAttempts = ctx.options.maxRetries + 1;
54
85
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
55
86
  try {
56
- const res = await fetch(url, {
87
+ const init = {
88
+ ...ctx.options.fetchOptions,
57
89
  method: opts.method,
58
- headers,
90
+ headers: finalHeaders,
59
91
  body: requestBody,
60
92
  signal: opts.signal
61
- });
93
+ };
94
+ const doFetch = ctx.options.fetch;
95
+ const res = doFetch ? await doFetch(url, init) : await fetch(url, init);
62
96
  if (res.ok) {
63
97
  const text = await res.text();
64
98
  const data = text ? JSON.parse(text) : void 0;
@@ -96,15 +130,6 @@ async function request(ctx, opts) {
96
130
  }
97
131
  return { data: null, error: lastError, headers: new Headers() };
98
132
  }
99
- function buildURL(base, path, params) {
100
- const url = new URL(path, base.endsWith("/") ? base : `${base}/`);
101
- if (params) {
102
- for (const [k, v] of Object.entries(params)) {
103
- url.searchParams.set(k, v);
104
- }
105
- }
106
- return url.toString();
107
- }
108
133
  function backoff(attempt) {
109
134
  return Math.min(1e3 * 2 ** attempt, 3e4);
110
135
  }
@@ -138,7 +163,7 @@ var DLQNamespace = class {
138
163
  async list(opts) {
139
164
  const { data, error } = await request(this._ctx, {
140
165
  method: "GET",
141
- path: "/v1/dlq/stats",
166
+ path: "/v1/ops/dlq/stats",
142
167
  signal: opts?.signal
143
168
  });
144
169
  if (error) return err(error);
@@ -148,7 +173,7 @@ var DLQNamespace = class {
148
173
  async table(name, opts) {
149
174
  const { data, error } = await request(this._ctx, {
150
175
  method: "GET",
151
- path: "/v1/dlq/stats",
176
+ path: "/v1/ops/dlq/stats",
152
177
  params: { table: name },
153
178
  signal: opts?.signal
154
179
  });
@@ -173,7 +198,14 @@ var PipeRef = class {
173
198
  this._params = params;
174
199
  this._createStream = createStream;
175
200
  }
176
- /** Execute the pipe and return results. */
201
+ /**
202
+ * Execute the pipe and return results.
203
+ *
204
+ * Takes only `signal` — deliberately narrower than the `RequestOptions` the
205
+ * query builder accepts. The pipes endpoint binds the body as the pipe's
206
+ * parameters, so there is no row cap to forward; give the pipe a `{{limit}}`
207
+ * parameter in its SQL and pass it via `wh.pipe(name, { limit })`.
208
+ */
177
209
  async fetch(opts) {
178
210
  const { data, error } = await request(this._ctx, {
179
211
  method: "POST",
@@ -201,7 +233,7 @@ var PipesNamespace = class {
201
233
  async list(opts) {
202
234
  const { data, error } = await request(this._ctx, {
203
235
  method: "GET",
204
- path: "/v1/admin/pipes",
236
+ path: "/v1/ops/pipes",
205
237
  signal: opts?.signal
206
238
  });
207
239
  if (error) return err(error);
@@ -211,7 +243,7 @@ var PipesNamespace = class {
211
243
  async get(name, opts) {
212
244
  const { data, error } = await request(this._ctx, {
213
245
  method: "GET",
214
- path: `/v1/admin/pipes/${encodeURIComponent(name)}`,
246
+ path: `/v1/ops/pipes/${encodeURIComponent(name)}`,
215
247
  signal: opts?.signal
216
248
  });
217
249
  if (error) return err(error);
@@ -221,7 +253,7 @@ var PipesNamespace = class {
221
253
  async set(name, def, opts) {
222
254
  const { error } = await request(this._ctx, {
223
255
  method: "PUT",
224
- path: `/v1/admin/pipes/${encodeURIComponent(name)}`,
256
+ path: `/v1/ops/pipes/${encodeURIComponent(name)}`,
225
257
  body: def,
226
258
  signal: opts?.signal
227
259
  });
@@ -232,7 +264,7 @@ var PipesNamespace = class {
232
264
  async delete(name, opts) {
233
265
  const { error } = await request(this._ctx, {
234
266
  method: "DELETE",
235
- path: `/v1/admin/pipes/${encodeURIComponent(name)}`,
267
+ path: `/v1/ops/pipes/${encodeURIComponent(name)}`,
236
268
  signal: opts?.signal
237
269
  });
238
270
  if (error) return err(error);
@@ -250,7 +282,7 @@ var PolicyNamespace = class {
250
282
  async get(opts) {
251
283
  const { data, error } = await request(this._ctx, {
252
284
  method: "GET",
253
- path: "/v1/admin/policy",
285
+ path: "/v1/ops/policy",
254
286
  signal: opts?.signal
255
287
  });
256
288
  if (error) return err(error);
@@ -260,7 +292,7 @@ var PolicyNamespace = class {
260
292
  async set(policy, opts) {
261
293
  const { error } = await request(this._ctx, {
262
294
  method: "PUT",
263
- path: "/v1/admin/policy",
295
+ path: "/v1/ops/policy",
264
296
  body: policy,
265
297
  signal: opts?.signal
266
298
  });
@@ -271,7 +303,7 @@ var PolicyNamespace = class {
271
303
  async validate(policy, opts) {
272
304
  const { data, error } = await request(this._ctx, {
273
305
  method: "POST",
274
- path: "/v1/admin/policy/validate",
306
+ path: "/v1/ops/policy/validate",
275
307
  body: policy,
276
308
  signal: opts?.signal
277
309
  });
@@ -290,7 +322,7 @@ var SchemaNamespace = class {
290
322
  async list(opts) {
291
323
  const { data, error } = await request(this._ctx, {
292
324
  method: "GET",
293
- path: "/v1/schema",
325
+ path: "/v1/ops/schema",
294
326
  signal: opts?.signal
295
327
  });
296
328
  if (error) return err(error);
@@ -311,7 +343,7 @@ var SchemaNamespace = class {
311
343
  async refresh(opts) {
312
344
  const { error } = await request(this._ctx, {
313
345
  method: "POST",
314
- path: "/v1/schema/refresh",
346
+ path: "/v1/ops/schema/refresh",
315
347
  signal: opts?.signal
316
348
  });
317
349
  if (error) return err(error);
@@ -323,7 +355,7 @@ var SchemaNamespace = class {
323
355
  async function sql(ctx, query, opts) {
324
356
  const { data, error } = await request(ctx, {
325
357
  method: "POST",
326
- path: "/v1/admin/query",
358
+ path: "/v1/ops/query",
327
359
  body: { sql: query },
328
360
  signal: opts?.signal
329
361
  });
@@ -521,7 +553,7 @@ var SSETransport = class {
521
553
  this.onStatus?.("closed");
522
554
  }
523
555
  async _doConnect() {
524
- const url = new URL("/v1/stream", this._opts.baseURL);
556
+ const url = resolveURL(this._opts.baseURL, "/v1/stream");
525
557
  url.searchParams.set("table", this._opts.table);
526
558
  if (this._opts.since) {
527
559
  url.searchParams.set("since", this._opts.since);
@@ -1035,7 +1067,7 @@ var TableRef = class {
1035
1067
  async schema(opts) {
1036
1068
  const { data, error } = await request(this._ctx, {
1037
1069
  method: "GET",
1038
- path: `/v1/schema?table=${encodeURIComponent(this._table)}`,
1070
+ path: `/v1/ops/schema?table=${encodeURIComponent(this._table)}`,
1039
1071
  signal: opts?.signal
1040
1072
  });
1041
1073
  if (error) return err(error);
@@ -1066,7 +1098,10 @@ var WaveHouseClient = class {
1066
1098
  baseURL: config.baseURL.replace(/\/+$/, ""),
1067
1099
  auth: config.auth,
1068
1100
  options: {
1069
- maxRetries: config.options?.maxRetries ?? 2
1101
+ maxRetries: config.options?.maxRetries ?? 2,
1102
+ fetch: config.options?.fetch,
1103
+ headers: config.options?.headers,
1104
+ fetchOptions: config.options?.fetchOptions
1070
1105
  }
1071
1106
  };
1072
1107
  this.schema = new SchemaNamespace(this._ctx);
@@ -1098,7 +1133,7 @@ var WaveHouseClient = class {
1098
1133
  sql(query, opts) {
1099
1134
  if (Array.isArray(opts)) {
1100
1135
  throw new Error(
1101
- "[WaveHouse SDK] client.sql(sql, params) was removed. The /v1/admin/query endpoint does not accept positional `?` params. Inline literals into the SQL, or use the structured query builder (wh.from(table)\u2026) for safe binding from user input."
1136
+ "[WaveHouse SDK] client.sql(sql, params) was removed. The /v1/ops/query endpoint does not accept positional `?` params. Inline literals into the SQL, or use the structured query builder (wh.from(table)\u2026) for safe binding from user input."
1102
1137
  );
1103
1138
  }
1104
1139
  return sql(this._ctx, query, opts);