@blimu/client 0.7.0 → 1.1.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.
Files changed (54) hide show
  1. package/README.md +26 -79
  2. package/dist/client.d.mts +15 -59
  3. package/dist/client.d.ts +15 -59
  4. package/dist/client.js +1085 -110
  5. package/dist/client.js.map +1 -0
  6. package/dist/client.mjs +1112 -4
  7. package/dist/client.mjs.map +1 -0
  8. package/dist/index.d.mts +10 -3
  9. package/dist/index.d.ts +10 -3
  10. package/dist/index.js +1227 -133
  11. package/dist/index.js.map +1 -0
  12. package/dist/index.mjs +1317 -20
  13. package/dist/index.mjs.map +1 -0
  14. package/dist/{schema-jwKwV_Bm.d.mts → schema-B4iFbKly.d.mts} +4 -15
  15. package/dist/{schema-jwKwV_Bm.d.ts → schema-B4iFbKly.d.ts} +4 -15
  16. package/dist/schema.d.mts +2 -1
  17. package/dist/schema.d.ts +2 -1
  18. package/dist/schema.js +1 -1
  19. package/dist/schema.js.map +1 -0
  20. package/dist/schema.mjs +1 -1
  21. package/dist/schema.mjs.map +1 -0
  22. package/dist/schema.zod-CyY7RTSY.d.mts +48 -0
  23. package/dist/schema.zod-CyY7RTSY.d.ts +48 -0
  24. package/dist/schema.zod.d.mts +2 -0
  25. package/dist/schema.zod.d.ts +2 -0
  26. package/dist/schema.zod.js +76 -0
  27. package/dist/schema.zod.js.map +1 -0
  28. package/dist/schema.zod.mjs +47 -0
  29. package/dist/schema.zod.mjs.map +1 -0
  30. package/dist/services/auth.d.mts +3 -25
  31. package/dist/services/auth.d.ts +3 -25
  32. package/dist/services/auth.js +7 -10
  33. package/dist/services/auth.js.map +1 -0
  34. package/dist/services/auth.mjs +59 -5
  35. package/dist/services/auth.mjs.map +1 -0
  36. package/dist/services/entitlements.d.mts +3 -11
  37. package/dist/services/entitlements.d.ts +3 -11
  38. package/dist/services/entitlements.js +8 -7
  39. package/dist/services/entitlements.js.map +1 -0
  40. package/dist/services/entitlements.mjs +28 -5
  41. package/dist/services/entitlements.mjs.map +1 -0
  42. package/dist/tsconfig.tsbuildinfo +1 -0
  43. package/dist/utils.d.mts +2 -0
  44. package/dist/utils.d.ts +2 -0
  45. package/dist/utils.js +1078 -4
  46. package/dist/utils.js.map +1 -0
  47. package/dist/utils.mjs +1092 -5
  48. package/dist/utils.mjs.map +1 -0
  49. package/package.json +18 -40
  50. package/dist/chunk-7SBLH5KM.mjs +0 -6
  51. package/dist/chunk-ATZGLDGF.mjs +0 -143
  52. package/dist/chunk-ENXZU3RF.mjs +0 -30
  53. package/dist/chunk-LZ27JJ4R.mjs +0 -25
  54. package/dist/chunk-YGEJFE6U.mjs +0 -65
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __defProp = Object.defineProperty;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -21,157 +20,1165 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
20
  var index_exports = {};
22
21
  __export(index_exports, {
23
22
  AuthService: () => AuthService,
23
+ BadGatewayError: () => BadGatewayError,
24
+ BadRequestError: () => BadRequestError,
24
25
  Blimu: () => Blimu,
25
26
  BlimuError: () => BlimuError,
27
+ ClientError: () => ClientError,
28
+ ConflictError: () => ConflictError,
29
+ CoreClient: () => CoreClient,
26
30
  EntitlementsService: () => EntitlementsService,
31
+ FetchClient: () => FetchClient,
27
32
  FetchError: () => FetchError,
33
+ ForbiddenError: () => ForbiddenError,
34
+ GatewayTimeoutError: () => GatewayTimeoutError,
35
+ HookRegistry: () => HookRegistry,
36
+ InternalServerError: () => InternalServerError,
37
+ MethodNotAllowedError: () => MethodNotAllowedError,
38
+ NotFoundError: () => NotFoundError,
28
39
  Schema: () => schema_exports,
40
+ ServerError: () => ServerError,
41
+ ServiceUnavailableError: () => ServiceUnavailableError,
42
+ TooManyRequestsError: () => TooManyRequestsError,
43
+ UnauthorizedError: () => UnauthorizedError,
44
+ UnprocessableEntityError: () => UnprocessableEntityError,
45
+ ZodSchema: () => schema_zod_exports,
46
+ buildUrl: () => buildUrl,
47
+ calculateRetryDelay: () => calculateRetryDelay,
48
+ createFetchError: () => createFetchError,
49
+ encodeBase64: () => encodeBase64,
50
+ exponentialStrategy: () => exponentialStrategy,
51
+ getContentType: () => getContentType,
52
+ getFetchErrorMessage: () => getFetchErrorMessage,
53
+ getRetryStrategy: () => getRetryStrategy,
54
+ isAbortControllerAvailable: () => isAbortControllerAvailable,
55
+ isBrowser: () => isBrowser,
56
+ isFetchAvailable: () => isFetchAvailable,
57
+ isNode: () => isNode,
58
+ isSuccessResponse: () => isSuccessResponse,
59
+ linearStrategy: () => linearStrategy,
29
60
  listAll: () => listAll,
30
- paginate: () => paginate
61
+ paginate: () => paginate,
62
+ parseChunkedStream: () => parseChunkedStream,
63
+ parseNDJSONStream: () => parseNDJSONStream,
64
+ parseResponse: () => parseResponse,
65
+ parseSSEStream: () => parseSSEStream,
66
+ serializeBody: () => serializeBody,
67
+ serializeQueryParams: () => serializeQueryParams
31
68
  });
32
69
  module.exports = __toCommonJS(index_exports);
33
70
 
34
- // src/client.ts
35
- var FetchError = class extends Error {
71
+ // ../../node_modules/@blimu/fetch/dist/index.js
72
+ var __defProp2 = Object.defineProperty;
73
+ var __name = (target, value) => __defProp2(target, "name", { value, configurable: true });
74
+ var FetchError = class _FetchError extends Error {
75
+ static {
76
+ __name(this, "FetchError");
77
+ }
78
+ status;
79
+ data;
80
+ headers;
36
81
  constructor(message, status, data, headers) {
37
- super(message);
38
- this.status = status;
39
- this.data = data;
40
- this.headers = headers;
82
+ super(message), this.status = status, this.data = data, this.headers = headers;
41
83
  this.name = "FetchError";
84
+ if (Error.captureStackTrace) {
85
+ Error.captureStackTrace(this, _FetchError);
86
+ }
42
87
  }
43
88
  };
44
- var CoreClient = class {
45
- constructor(cfg = {}) {
46
- this.cfg = cfg;
47
- if (!this.cfg.baseURL) {
48
- if (this.cfg.env && this.cfg.envBaseURLs) {
49
- this.cfg.baseURL = this.cfg.env === "production" ? this.cfg.envBaseURLs.production : this.cfg.envBaseURLs.sandbox;
50
- } else {
51
- this.cfg.baseURL = "https://api.blimu.dev";
89
+ var ClientError = class extends FetchError {
90
+ static {
91
+ __name(this, "ClientError");
92
+ }
93
+ constructor(message, status, data, headers) {
94
+ super(message, status, data, headers);
95
+ this.name = "ClientError";
96
+ }
97
+ };
98
+ var ServerError = class extends FetchError {
99
+ static {
100
+ __name(this, "ServerError");
101
+ }
102
+ constructor(message, status, data, headers) {
103
+ super(message, status, data, headers);
104
+ this.name = "ServerError";
105
+ }
106
+ };
107
+ var BadRequestError = class extends ClientError {
108
+ static {
109
+ __name(this, "BadRequestError");
110
+ }
111
+ constructor(message = "Bad Request", data, headers) {
112
+ super(message, 400, data, headers);
113
+ this.name = "BadRequestError";
114
+ }
115
+ };
116
+ var UnauthorizedError = class extends ClientError {
117
+ static {
118
+ __name(this, "UnauthorizedError");
119
+ }
120
+ constructor(message = "Unauthorized", data, headers) {
121
+ super(message, 401, data, headers);
122
+ this.name = "UnauthorizedError";
123
+ }
124
+ };
125
+ var ForbiddenError = class extends ClientError {
126
+ static {
127
+ __name(this, "ForbiddenError");
128
+ }
129
+ constructor(message = "Forbidden", data, headers) {
130
+ super(message, 403, data, headers);
131
+ this.name = "ForbiddenError";
132
+ }
133
+ };
134
+ var NotFoundError = class extends ClientError {
135
+ static {
136
+ __name(this, "NotFoundError");
137
+ }
138
+ constructor(message = "Not Found", data, headers) {
139
+ super(message, 404, data, headers);
140
+ this.name = "NotFoundError";
141
+ }
142
+ };
143
+ var MethodNotAllowedError = class extends ClientError {
144
+ static {
145
+ __name(this, "MethodNotAllowedError");
146
+ }
147
+ constructor(message = "Method Not Allowed", data, headers) {
148
+ super(message, 405, data, headers);
149
+ this.name = "MethodNotAllowedError";
150
+ }
151
+ };
152
+ var ConflictError = class extends ClientError {
153
+ static {
154
+ __name(this, "ConflictError");
155
+ }
156
+ constructor(message = "Conflict", data, headers) {
157
+ super(message, 409, data, headers);
158
+ this.name = "ConflictError";
159
+ }
160
+ };
161
+ var UnprocessableEntityError = class extends ClientError {
162
+ static {
163
+ __name(this, "UnprocessableEntityError");
164
+ }
165
+ constructor(message = "Unprocessable Entity", data, headers) {
166
+ super(message, 422, data, headers);
167
+ this.name = "UnprocessableEntityError";
168
+ }
169
+ };
170
+ var TooManyRequestsError = class extends ClientError {
171
+ static {
172
+ __name(this, "TooManyRequestsError");
173
+ }
174
+ constructor(message = "Too Many Requests", data, headers) {
175
+ super(message, 429, data, headers);
176
+ this.name = "TooManyRequestsError";
177
+ }
178
+ };
179
+ var InternalServerError = class extends ServerError {
180
+ static {
181
+ __name(this, "InternalServerError");
182
+ }
183
+ constructor(message = "Internal Server Error", data, headers) {
184
+ super(message, 500, data, headers);
185
+ this.name = "InternalServerError";
186
+ }
187
+ };
188
+ var BadGatewayError = class extends ServerError {
189
+ static {
190
+ __name(this, "BadGatewayError");
191
+ }
192
+ constructor(message = "Bad Gateway", data, headers) {
193
+ super(message, 502, data, headers);
194
+ this.name = "BadGatewayError";
195
+ }
196
+ };
197
+ var ServiceUnavailableError = class extends ServerError {
198
+ static {
199
+ __name(this, "ServiceUnavailableError");
200
+ }
201
+ constructor(message = "Service Unavailable", data, headers) {
202
+ super(message, 503, data, headers);
203
+ this.name = "ServiceUnavailableError";
204
+ }
205
+ };
206
+ var GatewayTimeoutError = class extends ServerError {
207
+ static {
208
+ __name(this, "GatewayTimeoutError");
209
+ }
210
+ constructor(message = "Gateway Timeout", data, headers) {
211
+ super(message, 504, data, headers);
212
+ this.name = "GatewayTimeoutError";
213
+ }
214
+ };
215
+ function createFetchError(status, message, data, headers) {
216
+ const defaultMessage = message || `HTTP ${status}`;
217
+ switch (status) {
218
+ case 400:
219
+ return new BadRequestError(defaultMessage, data, headers);
220
+ case 401:
221
+ return new UnauthorizedError(defaultMessage, data, headers);
222
+ case 403:
223
+ return new ForbiddenError(defaultMessage, data, headers);
224
+ case 404:
225
+ return new NotFoundError(defaultMessage, data, headers);
226
+ case 405:
227
+ return new MethodNotAllowedError(defaultMessage, data, headers);
228
+ case 409:
229
+ return new ConflictError(defaultMessage, data, headers);
230
+ case 422:
231
+ return new UnprocessableEntityError(defaultMessage, data, headers);
232
+ case 429:
233
+ return new TooManyRequestsError(defaultMessage, data, headers);
234
+ // Generic 4xx
235
+ case 402:
236
+ case 406:
237
+ case 407:
238
+ case 408:
239
+ case 410:
240
+ case 411:
241
+ case 412:
242
+ case 413:
243
+ case 414:
244
+ case 415:
245
+ case 416:
246
+ case 417:
247
+ case 418:
248
+ case 421:
249
+ case 423:
250
+ case 424:
251
+ case 425:
252
+ case 426:
253
+ case 428:
254
+ case 431:
255
+ case 451:
256
+ return new ClientError(defaultMessage, status, data, headers);
257
+ // 5xx Server Errors
258
+ case 500:
259
+ return new InternalServerError(defaultMessage, data, headers);
260
+ case 502:
261
+ return new BadGatewayError(defaultMessage, data, headers);
262
+ case 503:
263
+ return new ServiceUnavailableError(defaultMessage, data, headers);
264
+ case 504:
265
+ return new GatewayTimeoutError(defaultMessage, data, headers);
266
+ // Generic 5xx
267
+ case 501:
268
+ case 505:
269
+ case 506:
270
+ case 507:
271
+ case 508:
272
+ case 510:
273
+ case 511:
274
+ return new ServerError(defaultMessage, status, data, headers);
275
+ default:
276
+ return new FetchError(defaultMessage, status, data, headers);
277
+ }
278
+ }
279
+ __name(createFetchError, "createFetchError");
280
+ var HookRegistry = class {
281
+ static {
282
+ __name(this, "HookRegistry");
283
+ }
284
+ hooks = /* @__PURE__ */ new Map();
285
+ constructor(config) {
286
+ if (config) {
287
+ this.registerFromConfig(config);
288
+ }
289
+ }
290
+ /**
291
+ * Register hooks from a configuration object
292
+ */
293
+ registerFromConfig(config) {
294
+ for (const [stage, hooks] of Object.entries(config)) {
295
+ if (hooks && Array.isArray(hooks)) {
296
+ for (const hook of hooks) {
297
+ this.register(stage, hook);
298
+ }
52
299
  }
53
300
  }
54
301
  }
55
- setAccessToken(token) {
56
- this.cfg.accessToken = token;
302
+ /**
303
+ * Register a hook for a specific stage
304
+ */
305
+ register(stage, hook) {
306
+ if (!this.hooks.has(stage)) {
307
+ this.hooks.set(stage, []);
308
+ }
309
+ this.hooks.get(stage).push(hook);
57
310
  }
58
- async request(init) {
59
- var _a, _b, _c;
60
- let normalizedPath = init.path || "";
61
- if (normalizedPath.length > 1 && normalizedPath.endsWith("/")) {
62
- normalizedPath = normalizedPath.slice(0, -1);
63
- }
64
- const url = new URL((this.cfg.baseURL || "") + normalizedPath);
65
- if (init.query) {
66
- Object.entries(init.query).forEach(([k, v]) => {
67
- if (v === void 0 || v === null) return;
68
- if (Array.isArray(v)) v.forEach((vv) => url.searchParams.append(k, String(vv)));
69
- else url.searchParams.set(k, String(v));
311
+ /**
312
+ * Remove a specific hook from a stage
313
+ */
314
+ remove(stage, hook) {
315
+ const hooks = this.hooks.get(stage);
316
+ if (!hooks) {
317
+ return false;
318
+ }
319
+ const index = hooks.indexOf(hook);
320
+ if (index === -1) {
321
+ return false;
322
+ }
323
+ hooks.splice(index, 1);
324
+ return true;
325
+ }
326
+ /**
327
+ * Clear all hooks for a specific stage, or all hooks if no stage is provided
328
+ */
329
+ clear(stage) {
330
+ if (stage) {
331
+ this.hooks.delete(stage);
332
+ } else {
333
+ this.hooks.clear();
334
+ }
335
+ }
336
+ /**
337
+ * Get all hooks for a specific stage
338
+ */
339
+ get(stage) {
340
+ return this.hooks.get(stage) || [];
341
+ }
342
+ /**
343
+ * Execute all hooks for a specific stage in registration order
344
+ */
345
+ async execute(stage, context) {
346
+ const hooks = this.get(stage);
347
+ for (const hook of hooks) {
348
+ await hook(context);
349
+ }
350
+ }
351
+ /**
352
+ * Check if any hooks are registered for a stage
353
+ */
354
+ has(stage) {
355
+ return this.hooks.has(stage) && this.hooks.get(stage).length > 0;
356
+ }
357
+ };
358
+ var exponentialStrategy = /* @__PURE__ */ __name((attempt, baseBackoffMs) => {
359
+ return baseBackoffMs * Math.pow(2, attempt);
360
+ }, "exponentialStrategy");
361
+ var linearStrategy = /* @__PURE__ */ __name((attempt, baseBackoffMs) => {
362
+ return baseBackoffMs * (attempt + 1);
363
+ }, "linearStrategy");
364
+ function getRetryStrategy(strategy) {
365
+ if (typeof strategy === "function") {
366
+ return strategy;
367
+ }
368
+ switch (strategy) {
369
+ case "exponential":
370
+ return exponentialStrategy;
371
+ case "linear":
372
+ return linearStrategy;
373
+ default:
374
+ return exponentialStrategy;
375
+ }
376
+ }
377
+ __name(getRetryStrategy, "getRetryStrategy");
378
+ function calculateRetryDelay(attempt, strategy, baseBackoffMs) {
379
+ const strategyFn = getRetryStrategy(strategy);
380
+ return strategyFn(attempt, baseBackoffMs);
381
+ }
382
+ __name(calculateRetryDelay, "calculateRetryDelay");
383
+ async function* parseSSEStream(response) {
384
+ if (!response.body) {
385
+ return;
386
+ }
387
+ const reader = response.body.getReader();
388
+ const decoder = new TextDecoder();
389
+ let buffer = "";
390
+ try {
391
+ while (true) {
392
+ const { done, value } = await reader.read();
393
+ if (done) break;
394
+ buffer += decoder.decode(value, {
395
+ stream: true
70
396
  });
397
+ const lines = buffer.split("\n");
398
+ buffer = lines.pop() || "";
399
+ let currentEvent = {};
400
+ for (const line of lines) {
401
+ if (line.trim() === "") {
402
+ if (currentEvent.data !== void 0) {
403
+ yield currentEvent.data;
404
+ }
405
+ currentEvent = {};
406
+ continue;
407
+ }
408
+ const colonIndex = line.indexOf(":");
409
+ if (colonIndex === -1) continue;
410
+ const field = line.substring(0, colonIndex).trim();
411
+ const value2 = line.substring(colonIndex + 1).trim();
412
+ if (field === "data") {
413
+ currentEvent.data = currentEvent.data ? currentEvent.data + "\n" + value2 : value2;
414
+ } else if (field === "event") {
415
+ currentEvent.type = value2;
416
+ } else if (field === "id") {
417
+ currentEvent.id = value2;
418
+ }
419
+ }
71
420
  }
72
- const headers = new Headers({
73
- ...this.cfg.headers || {},
74
- ...init.headers
75
- });
76
- if (this.cfg.accessToken) {
77
- const token = typeof this.cfg.accessToken === "function" ? await this.cfg.accessToken() : this.cfg.accessToken;
78
- if (token != null) {
79
- const name = this.cfg.headerName || "Authorization";
80
- if (name.toLowerCase() === "authorization") headers.set(name, `Bearer ${String(token)}`);
81
- else headers.set(name, String(token));
82
- }
83
- }
84
- if (this.cfg.bearer) headers.set("Authorization", `Bearer ${this.cfg.bearer}`);
85
- const doFetch = async (attempt) => {
86
- const requestHeaders = new Headers(headers);
87
- const fetchInit = {
88
- ...init,
89
- headers: requestHeaders
90
- };
91
- if (this.cfg.credentials !== void 0) {
92
- fetchInit.credentials = this.cfg.credentials;
93
- }
94
- if (this.cfg.onRequest)
95
- await this.cfg.onRequest({ url: url.toString(), init: fetchInit, attempt });
96
- let controller;
97
- let timeoutId;
98
- const existingSignal = fetchInit.signal;
99
- if (this.cfg.timeoutMs && typeof AbortController !== "undefined") {
100
- controller = new AbortController();
101
- if (existingSignal) {
102
- if (existingSignal.aborted) {
103
- controller.abort();
104
- } else {
105
- existingSignal.addEventListener("abort", () => {
106
- controller == null ? void 0 : controller.abort();
107
- });
421
+ if (buffer.trim()) {
422
+ const lines = buffer.split("\n");
423
+ let currentEvent = {};
424
+ for (const line of lines) {
425
+ if (line.trim() === "" && currentEvent.data !== void 0) {
426
+ yield currentEvent.data;
427
+ currentEvent = {};
428
+ continue;
429
+ }
430
+ const colonIndex = line.indexOf(":");
431
+ if (colonIndex !== -1) {
432
+ const field = line.substring(0, colonIndex).trim();
433
+ const value = line.substring(colonIndex + 1).trim();
434
+ if (field === "data") {
435
+ currentEvent.data = currentEvent.data ? currentEvent.data + "\n" + value : value;
108
436
  }
109
437
  }
110
- fetchInit.signal = controller.signal;
111
- timeoutId = setTimeout(() => controller == null ? void 0 : controller.abort(), this.cfg.timeoutMs);
112
438
  }
439
+ if (currentEvent.data !== void 0) {
440
+ yield currentEvent.data;
441
+ }
442
+ }
443
+ } finally {
444
+ reader.releaseLock();
445
+ }
446
+ }
447
+ __name(parseSSEStream, "parseSSEStream");
448
+ async function* parseNDJSONStream(response) {
449
+ if (!response.body) {
450
+ return;
451
+ }
452
+ const reader = response.body.getReader();
453
+ const decoder = new TextDecoder();
454
+ let buffer = "";
455
+ try {
456
+ while (true) {
457
+ const { done, value } = await reader.read();
458
+ if (done) break;
459
+ buffer += decoder.decode(value, {
460
+ stream: true
461
+ });
462
+ const lines = buffer.split("\n");
463
+ buffer = lines.pop() || "";
464
+ for (const line of lines) {
465
+ const trimmed = line.trim();
466
+ if (trimmed === "") continue;
467
+ try {
468
+ const parsed = JSON.parse(trimmed);
469
+ yield parsed;
470
+ } catch (error) {
471
+ console.warn("Skipping invalid JSON line:", trimmed);
472
+ }
473
+ }
474
+ }
475
+ if (buffer.trim()) {
113
476
  try {
114
- const res = await (this.cfg.fetch || fetch)(url.toString(), fetchInit);
115
- if (this.cfg.onResponse)
116
- await this.cfg.onResponse({
117
- url: url.toString(),
118
- init: fetchInit,
119
- attempt,
120
- response: res
121
- });
122
- const ct = res.headers.get("content-type") || "";
123
- let parsed;
124
- if (ct.includes("application/json")) {
125
- parsed = await res.json();
126
- } else if (ct.startsWith("text/")) {
127
- parsed = await res.text();
477
+ const parsed = JSON.parse(buffer.trim());
478
+ yield parsed;
479
+ } catch (error) {
480
+ console.warn("Skipping invalid JSON in buffer:", buffer.trim());
481
+ }
482
+ }
483
+ } finally {
484
+ reader.releaseLock();
485
+ }
486
+ }
487
+ __name(parseNDJSONStream, "parseNDJSONStream");
488
+ async function* parseChunkedStream(response) {
489
+ if (!response.body) {
490
+ return;
491
+ }
492
+ const reader = response.body.getReader();
493
+ const decoder = new TextDecoder();
494
+ try {
495
+ while (true) {
496
+ const { done, value } = await reader.read();
497
+ if (done) break;
498
+ const chunk = decoder.decode(value, {
499
+ stream: true
500
+ });
501
+ yield chunk;
502
+ }
503
+ } finally {
504
+ reader.releaseLock();
505
+ }
506
+ }
507
+ __name(parseChunkedStream, "parseChunkedStream");
508
+ function isBrowser() {
509
+ return typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined" && typeof globalThis.window.document !== "undefined";
510
+ }
511
+ __name(isBrowser, "isBrowser");
512
+ function isNode() {
513
+ return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
514
+ }
515
+ __name(isNode, "isNode");
516
+ function encodeBase64(str) {
517
+ if (isBrowser()) {
518
+ if (typeof btoa !== "undefined") {
519
+ return btoa(str);
520
+ }
521
+ throw new Error("btoa is not available. This should not happen in a browser environment.");
522
+ } else {
523
+ if (typeof Buffer !== "undefined") {
524
+ return Buffer.from(str, "utf-8").toString("base64");
525
+ }
526
+ throw new Error("Buffer is not available. Please ensure you're running in Node.js or provide a polyfill.");
527
+ }
528
+ }
529
+ __name(encodeBase64, "encodeBase64");
530
+ function isFetchAvailable() {
531
+ return typeof fetch !== "undefined";
532
+ }
533
+ __name(isFetchAvailable, "isFetchAvailable");
534
+ function isAbortControllerAvailable() {
535
+ return typeof AbortController !== "undefined";
536
+ }
537
+ __name(isAbortControllerAvailable, "isAbortControllerAvailable");
538
+ function getFetchErrorMessage() {
539
+ if (isBrowser()) {
540
+ return "fetch is not available in this browser. Please use a modern browser or provide a polyfill.";
541
+ } else {
542
+ return "fetch is not available. Node.js 22+ includes native fetch. For older versions, please provide a custom fetch implementation (e.g., from 'undici' or 'node-fetch').";
543
+ }
544
+ }
545
+ __name(getFetchErrorMessage, "getFetchErrorMessage");
546
+ function serializeQueryParams(query) {
547
+ const params = new URLSearchParams();
548
+ for (const [key, value] of Object.entries(query)) {
549
+ if (value === void 0 || value === null) {
550
+ continue;
551
+ }
552
+ if (Array.isArray(value)) {
553
+ for (const item of value) {
554
+ if (item !== void 0 && item !== null) {
555
+ params.append(key, String(item));
556
+ }
557
+ }
558
+ } else {
559
+ params.set(key, String(value));
560
+ }
561
+ }
562
+ return params;
563
+ }
564
+ __name(serializeQueryParams, "serializeQueryParams");
565
+ function buildUrl(baseUrl, path, query) {
566
+ let normalizedPath = path || "";
567
+ if (normalizedPath.length > 1 && normalizedPath.endsWith("/")) {
568
+ normalizedPath = normalizedPath.slice(0, -1);
569
+ }
570
+ let normalizedBaseUrl = baseUrl || "";
571
+ if (normalizedBaseUrl) {
572
+ try {
573
+ const baseUrlObj = new URL(normalizedBaseUrl);
574
+ if (baseUrlObj.pathname && baseUrlObj.pathname !== "/" && !normalizedBaseUrl.endsWith("/")) {
575
+ normalizedBaseUrl = normalizedBaseUrl + "/";
576
+ }
577
+ } catch {
578
+ }
579
+ }
580
+ if (normalizedPath.startsWith("/")) {
581
+ normalizedPath = normalizedPath.slice(1);
582
+ }
583
+ const url = new URL(normalizedPath, normalizedBaseUrl);
584
+ if (query) {
585
+ const params = serializeQueryParams(query);
586
+ const keys = Array.from(new Set(params.keys()));
587
+ for (const key of keys) {
588
+ url.searchParams.delete(key);
589
+ for (const value of params.getAll(key)) {
590
+ url.searchParams.append(key, value);
591
+ }
592
+ }
593
+ }
594
+ return url;
595
+ }
596
+ __name(buildUrl, "buildUrl");
597
+ function getContentType(body) {
598
+ if (body === null || body === void 0) {
599
+ return void 0;
600
+ }
601
+ if (body instanceof FormData) {
602
+ return void 0;
603
+ }
604
+ if (body instanceof URLSearchParams) {
605
+ return "application/x-www-form-urlencoded";
606
+ }
607
+ if (typeof body === "string") {
608
+ try {
609
+ JSON.parse(body);
610
+ return "application/json";
611
+ } catch {
612
+ return "text/plain";
613
+ }
614
+ }
615
+ if (typeof body === "object") {
616
+ return "application/json";
617
+ }
618
+ return void 0;
619
+ }
620
+ __name(getContentType, "getContentType");
621
+ function serializeBody(body, contentType) {
622
+ if (body === null || body === void 0) {
623
+ return null;
624
+ }
625
+ if (typeof body === "string" || body instanceof FormData || body instanceof URLSearchParams || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {
626
+ return body;
627
+ }
628
+ if (contentType === "application/x-www-form-urlencoded" && typeof body === "object" && body !== null && !Array.isArray(body)) {
629
+ const params = new URLSearchParams();
630
+ for (const [key, value] of Object.entries(body)) {
631
+ if (value !== null && value !== void 0) {
632
+ if (Array.isArray(value)) {
633
+ for (const item of value) {
634
+ params.append(key, String(item));
635
+ }
128
636
  } else {
129
- parsed = await res.arrayBuffer();
637
+ params.append(key, String(value));
130
638
  }
131
- if (!res.ok) {
132
- throw new FetchError(
133
- (parsed == null ? void 0 : parsed.message) || `HTTP ${res.status}`,
134
- res.status,
135
- parsed,
136
- res.headers
137
- );
639
+ }
640
+ }
641
+ return params;
642
+ }
643
+ if (typeof body === "object") {
644
+ return JSON.stringify(body);
645
+ }
646
+ return String(body);
647
+ }
648
+ __name(serializeBody, "serializeBody");
649
+ async function parseResponse(response) {
650
+ const contentType = response.headers.get("content-type") || "";
651
+ if (contentType.includes("application/json")) {
652
+ return await response.json();
653
+ } else if (contentType.startsWith("text/")) {
654
+ return await response.text();
655
+ } else {
656
+ return await response.arrayBuffer();
657
+ }
658
+ }
659
+ __name(parseResponse, "parseResponse");
660
+ function isSuccessResponse(response) {
661
+ return response.ok;
662
+ }
663
+ __name(isSuccessResponse, "isSuccessResponse");
664
+ var FetchClient = class {
665
+ static {
666
+ __name(this, "FetchClient");
667
+ }
668
+ hookRegistry;
669
+ cfg;
670
+ constructor(config = {}) {
671
+ this.cfg = config;
672
+ if (!this.cfg.baseURL) {
673
+ this.cfg.baseURL = "";
674
+ }
675
+ this.hookRegistry = new HookRegistry(this.cfg.hooks);
676
+ if (!isFetchAvailable() && !this.cfg.fetch) {
677
+ throw new Error(getFetchErrorMessage());
678
+ }
679
+ }
680
+ /**
681
+ * Add an authentication strategy
682
+ */
683
+ addAuthStrategy(strategy) {
684
+ if (!this.cfg.auth) {
685
+ this.cfg.auth = {
686
+ strategies: []
687
+ };
688
+ }
689
+ this.cfg.auth.strategies.push(strategy);
690
+ }
691
+ /**
692
+ * Remove all authentication strategies
693
+ */
694
+ clearAuthStrategies() {
695
+ if (this.cfg.auth) {
696
+ this.cfg.auth.strategies = [];
697
+ }
698
+ }
699
+ /**
700
+ * Register a hook for a specific lifecycle stage
701
+ */
702
+ useHook(stage, hook) {
703
+ this.hookRegistry.register(stage, hook);
704
+ }
705
+ /**
706
+ * Remove a hook
707
+ */
708
+ removeHook(stage, hook) {
709
+ return this.hookRegistry.remove(stage, hook);
710
+ }
711
+ /**
712
+ * Clear hooks for a stage or all hooks
713
+ */
714
+ clearHooks(stage) {
715
+ this.hookRegistry.clear(stage);
716
+ }
717
+ /**
718
+ * Make an HTTP request
719
+ */
720
+ async request(init) {
721
+ let url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
722
+ const headers = new Headers(this.cfg.headers || {});
723
+ if (init.headers) {
724
+ if (init.headers instanceof Headers) {
725
+ init.headers.forEach((value, key) => {
726
+ headers.set(key, value);
727
+ });
728
+ } else {
729
+ Object.entries(init.headers).forEach(([key, value]) => {
730
+ headers.set(key, String(value));
731
+ });
732
+ }
733
+ }
734
+ await this.applyAuthentication(headers, url);
735
+ let bodyContentType;
736
+ if (init.body !== void 0) {
737
+ bodyContentType = headers.get("Content-Type") || void 0;
738
+ if (!bodyContentType) {
739
+ bodyContentType = getContentType(init.body);
740
+ if (bodyContentType) {
741
+ headers.set("Content-Type", bodyContentType);
138
742
  }
139
- return parsed;
140
- } catch (err) {
141
- if (this.cfg.onError) await this.cfg.onError(err, { url: url.toString(), init, attempt });
142
- throw err;
143
- } finally {
144
- if (timeoutId) clearTimeout(timeoutId);
145
743
  }
146
- };
147
- const retries = ((_a = this.cfg.retry) == null ? void 0 : _a.retries) ?? 0;
148
- const baseBackoff = ((_b = this.cfg.retry) == null ? void 0 : _b.backoffMs) ?? 300;
149
- const retryOn = ((_c = this.cfg.retry) == null ? void 0 : _c.retryOn) ?? [429, 500, 502, 503, 504];
744
+ }
745
+ const retries = this.cfg.retry?.retries ?? 0;
746
+ const baseBackoff = this.cfg.retry?.backoffMs ?? 300;
747
+ const retryOn = this.cfg.retry?.retryOn ?? [
748
+ 429,
749
+ 500,
750
+ 502,
751
+ 503,
752
+ 504
753
+ ];
754
+ const retryStrategy = this.cfg.retry?.strategy ?? "exponential";
150
755
  let lastError;
151
- for (let attempt = 0; attempt <= retries; attempt++) {
756
+ for (let attempt = 0; attempt <= retries + 1; attempt++) {
152
757
  try {
153
- return await doFetch(attempt);
758
+ let attemptUrl = buildUrl(this.cfg.baseURL || "", init.path, init.query);
759
+ const attemptHeaders = new Headers(headers);
760
+ await this.applyAuthentication(attemptHeaders, attemptUrl);
761
+ return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType);
154
762
  } catch (err) {
155
- const status = err == null ? void 0 : err.status;
156
- const shouldRetry = status ? retryOn.includes(status) : true;
157
- if (attempt < retries && shouldRetry) {
158
- const delay = baseBackoff * Math.pow(2, attempt);
159
- await new Promise((r) => setTimeout(r, delay));
160
- lastError = err;
763
+ lastError = err;
764
+ const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);
765
+ if (shouldRetry) {
766
+ if (this.hookRegistry.has("beforeRetry")) {
767
+ await this.hookRegistry.execute("beforeRetry", {
768
+ url: url.toString(),
769
+ init: {
770
+ ...init,
771
+ headers
772
+ },
773
+ attempt,
774
+ error: err,
775
+ retryCount: attempt
776
+ });
777
+ }
778
+ const delay = calculateRetryDelay(attempt, retryStrategy, baseBackoff);
779
+ await new Promise((resolve) => setTimeout(resolve, delay));
780
+ if (this.hookRegistry.has("afterRetry")) {
781
+ await this.hookRegistry.execute("afterRetry", {
782
+ url: url.toString(),
783
+ init: {
784
+ ...init,
785
+ headers
786
+ },
787
+ attempt,
788
+ error: err,
789
+ retryCount: attempt,
790
+ success: false
791
+ });
792
+ }
161
793
  continue;
162
794
  }
163
- if (err instanceof DOMException) throw err;
164
- if (err instanceof FetchError) throw err;
165
- if (typeof err === "string") throw new FetchError(err, status ?? 0);
166
- throw new FetchError((err == null ? void 0 : err.message) || "Network error", status ?? 0);
795
+ throw err;
167
796
  }
168
797
  }
169
798
  throw lastError;
170
799
  }
800
+ /**
801
+ * Make a streaming HTTP request
802
+ */
803
+ async *requestStream(init) {
804
+ let url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
805
+ const headers = new Headers(this.cfg.headers || {});
806
+ if (init.headers) {
807
+ if (init.headers instanceof Headers) {
808
+ init.headers.forEach((value, key) => {
809
+ headers.set(key, value);
810
+ });
811
+ } else {
812
+ Object.entries(init.headers).forEach(([key, value]) => {
813
+ headers.set(key, String(value));
814
+ });
815
+ }
816
+ }
817
+ await this.applyAuthentication(headers, url);
818
+ let bodyContentType = headers.get("Content-Type") || void 0;
819
+ if (init.contentType && !bodyContentType) {
820
+ bodyContentType = init.contentType;
821
+ headers.set("Content-Type", bodyContentType);
822
+ }
823
+ const fetchInit = {
824
+ ...init,
825
+ headers,
826
+ body: serializeBody(init.body, bodyContentType)
827
+ };
828
+ if (this.cfg.credentials !== void 0) {
829
+ fetchInit.credentials = this.cfg.credentials;
830
+ }
831
+ if (this.hookRegistry.has("beforeRequest")) {
832
+ await this.hookRegistry.execute("beforeRequest", {
833
+ url: url.toString(),
834
+ init: fetchInit,
835
+ attempt: 0
836
+ });
837
+ }
838
+ let controller;
839
+ let timeoutId;
840
+ const existingSignal = fetchInit.signal;
841
+ if (this.cfg.timeoutMs && typeof AbortController !== "undefined") {
842
+ controller = new AbortController();
843
+ if (existingSignal) {
844
+ if (existingSignal.aborted) {
845
+ controller.abort();
846
+ } else {
847
+ existingSignal.addEventListener("abort", () => {
848
+ controller?.abort();
849
+ });
850
+ }
851
+ }
852
+ fetchInit.signal = controller.signal;
853
+ timeoutId = setTimeout(() => {
854
+ controller?.abort();
855
+ if (this.hookRegistry.has("onTimeout")) {
856
+ this.hookRegistry.execute("onTimeout", {
857
+ url: url.toString(),
858
+ init: fetchInit,
859
+ attempt: 0,
860
+ timeoutMs: this.cfg.timeoutMs
861
+ });
862
+ }
863
+ }, this.cfg.timeoutMs);
864
+ }
865
+ try {
866
+ const fetchFn = this.cfg.fetch || fetch;
867
+ const res = await fetchFn(url.toString(), fetchInit);
868
+ if (this.hookRegistry.has("afterRequest")) {
869
+ await this.hookRegistry.execute("afterRequest", {
870
+ url: url.toString(),
871
+ init: fetchInit,
872
+ attempt: 0,
873
+ response: res
874
+ });
875
+ }
876
+ if (!res.ok) {
877
+ const parsed = await parseResponse(res);
878
+ const error = createFetchError(res.status, parsed?.message || `HTTP ${res.status}`, parsed, res.headers);
879
+ if (this.hookRegistry.has("onError")) {
880
+ await this.hookRegistry.execute("onError", {
881
+ url: url.toString(),
882
+ init: fetchInit,
883
+ attempt: 0,
884
+ error
885
+ });
886
+ }
887
+ throw error;
888
+ }
889
+ if (this.hookRegistry.has("onStreamStart")) {
890
+ await this.hookRegistry.execute("onStreamStart", {
891
+ url: url.toString(),
892
+ init: fetchInit,
893
+ attempt: 0,
894
+ response: res
895
+ });
896
+ }
897
+ const streamingFormat = init.streamingFormat || "chunked";
898
+ if (streamingFormat === "sse") {
899
+ for await (const chunk of parseSSEStream(res)) {
900
+ let transformedChunk = chunk;
901
+ if (this.hookRegistry.has("onStreamChunk")) {
902
+ await this.hookRegistry.execute("onStreamChunk", {
903
+ url: url.toString(),
904
+ init: fetchInit,
905
+ attempt: 0,
906
+ chunk
907
+ });
908
+ }
909
+ yield transformedChunk;
910
+ }
911
+ } else if (streamingFormat === "ndjson") {
912
+ for await (const chunk of parseNDJSONStream(res)) {
913
+ let transformedChunk = chunk;
914
+ if (this.hookRegistry.has("onStreamChunk")) {
915
+ await this.hookRegistry.execute("onStreamChunk", {
916
+ url: url.toString(),
917
+ init: fetchInit,
918
+ attempt: 0,
919
+ chunk
920
+ });
921
+ }
922
+ yield transformedChunk;
923
+ }
924
+ } else {
925
+ for await (const chunk of parseChunkedStream(res)) {
926
+ let transformedChunk = chunk;
927
+ if (this.hookRegistry.has("onStreamChunk")) {
928
+ await this.hookRegistry.execute("onStreamChunk", {
929
+ url: url.toString(),
930
+ init: fetchInit,
931
+ attempt: 0,
932
+ chunk
933
+ });
934
+ }
935
+ yield transformedChunk;
936
+ }
937
+ }
938
+ if (this.hookRegistry.has("onStreamEnd")) {
939
+ await this.hookRegistry.execute("onStreamEnd", {
940
+ url: url.toString(),
941
+ init: fetchInit,
942
+ attempt: 0,
943
+ response: res
944
+ });
945
+ }
946
+ } catch (err) {
947
+ if (this.hookRegistry.has("onError")) {
948
+ await this.hookRegistry.execute("onError", {
949
+ url: url.toString(),
950
+ init: fetchInit,
951
+ attempt: 0,
952
+ error: err
953
+ });
954
+ }
955
+ throw err;
956
+ } finally {
957
+ if (timeoutId) {
958
+ clearTimeout(timeoutId);
959
+ }
960
+ }
961
+ }
962
+ /**
963
+ * Internal method to execute a single request attempt
964
+ */
965
+ async doRequest(url, init, baseHeaders, attempt, contentType) {
966
+ const requestHeaders = baseHeaders;
967
+ const fetchInit = {
968
+ ...init,
969
+ headers: requestHeaders,
970
+ body: serializeBody(init.body, contentType)
971
+ };
972
+ if (this.cfg.credentials !== void 0) {
973
+ fetchInit.credentials = this.cfg.credentials;
974
+ }
975
+ if (this.hookRegistry.has("beforeRequest")) {
976
+ await this.hookRegistry.execute("beforeRequest", {
977
+ url: url.toString(),
978
+ init: fetchInit,
979
+ attempt
980
+ });
981
+ }
982
+ let controller;
983
+ let timeoutId;
984
+ const existingSignal = fetchInit.signal;
985
+ if (this.cfg.timeoutMs && typeof AbortController !== "undefined") {
986
+ controller = new AbortController();
987
+ if (existingSignal) {
988
+ if (existingSignal.aborted) {
989
+ controller.abort();
990
+ } else {
991
+ existingSignal.addEventListener("abort", () => {
992
+ controller?.abort();
993
+ });
994
+ }
995
+ }
996
+ fetchInit.signal = controller.signal;
997
+ timeoutId = setTimeout(() => {
998
+ controller?.abort();
999
+ if (this.hookRegistry.has("onTimeout")) {
1000
+ this.hookRegistry.execute("onTimeout", {
1001
+ url: url.toString(),
1002
+ init: fetchInit,
1003
+ attempt,
1004
+ timeoutMs: this.cfg.timeoutMs
1005
+ });
1006
+ }
1007
+ }, this.cfg.timeoutMs);
1008
+ }
1009
+ try {
1010
+ const fetchFn = this.cfg.fetch || fetch;
1011
+ const res = await fetchFn(url.toString(), fetchInit);
1012
+ if (this.hookRegistry.has("afterRequest")) {
1013
+ await this.hookRegistry.execute("afterRequest", {
1014
+ url: url.toString(),
1015
+ init: fetchInit,
1016
+ attempt,
1017
+ response: res
1018
+ });
1019
+ }
1020
+ const parsed = await parseResponse(res);
1021
+ if (this.hookRegistry.has("afterResponse")) {
1022
+ await this.hookRegistry.execute("afterResponse", {
1023
+ url: url.toString(),
1024
+ init: fetchInit,
1025
+ attempt,
1026
+ response: res,
1027
+ data: parsed
1028
+ });
1029
+ }
1030
+ if (!isSuccessResponse(res)) {
1031
+ const error = createFetchError(res.status, parsed?.message || `HTTP ${res.status}`, parsed, res.headers);
1032
+ if (this.hookRegistry.has("onError")) {
1033
+ await this.hookRegistry.execute("onError", {
1034
+ url: url.toString(),
1035
+ init: fetchInit,
1036
+ attempt,
1037
+ error
1038
+ });
1039
+ }
1040
+ throw error;
1041
+ }
1042
+ return parsed;
1043
+ } catch (err) {
1044
+ if (this.hookRegistry.has("onError")) {
1045
+ await this.hookRegistry.execute("onError", {
1046
+ url: url.toString(),
1047
+ init: fetchInit,
1048
+ attempt,
1049
+ error: err
1050
+ });
1051
+ }
1052
+ if (err instanceof DOMException) {
1053
+ throw err;
1054
+ }
1055
+ if (err instanceof FetchError) {
1056
+ throw err;
1057
+ }
1058
+ const status = err?.status;
1059
+ const statusCode = typeof status === "number" ? status : 0;
1060
+ if (typeof err === "string") {
1061
+ throw createFetchError(statusCode, err);
1062
+ }
1063
+ throw createFetchError(statusCode, err?.message || "Network error");
1064
+ } finally {
1065
+ if (timeoutId) {
1066
+ clearTimeout(timeoutId);
1067
+ }
1068
+ }
1069
+ }
1070
+ /**
1071
+ * Apply authentication strategies
1072
+ */
1073
+ async applyAuthentication(headers, url) {
1074
+ if (!this.cfg.auth?.strategies) {
1075
+ return;
1076
+ }
1077
+ for (const strategy of this.cfg.auth.strategies) {
1078
+ await this.applyAuthStrategy(strategy, headers, url);
1079
+ }
1080
+ }
1081
+ /**
1082
+ * Apply a single authentication strategy
1083
+ */
1084
+ async applyAuthStrategy(strategy, headers, url) {
1085
+ switch (strategy.type) {
1086
+ case "bearer": {
1087
+ const token = typeof strategy.token === "function" ? await strategy.token() : strategy.token;
1088
+ if (token != null) {
1089
+ const headerName = strategy.headerName || "Authorization";
1090
+ headers.set(headerName, `Bearer ${String(token)}`);
1091
+ }
1092
+ break;
1093
+ }
1094
+ case "basic": {
1095
+ const encoded = encodeBase64(`${strategy.username}:${strategy.password}`);
1096
+ headers.set("Authorization", `Basic ${encoded}`);
1097
+ break;
1098
+ }
1099
+ case "apiKey": {
1100
+ const key = typeof strategy.key === "function" ? await strategy.key() : strategy.key;
1101
+ if (key != null) {
1102
+ switch (strategy.location) {
1103
+ case "header":
1104
+ headers.set(strategy.name, String(key));
1105
+ break;
1106
+ case "query":
1107
+ url.searchParams.set(strategy.name, String(key));
1108
+ break;
1109
+ case "cookie":
1110
+ headers.set("Cookie", `${strategy.name}=${String(key)}`);
1111
+ break;
1112
+ }
1113
+ }
1114
+ break;
1115
+ }
1116
+ case "custom":
1117
+ await strategy.apply(headers, url);
1118
+ break;
1119
+ }
1120
+ }
1121
+ /**
1122
+ * Determine if an error should be retried
1123
+ */
1124
+ shouldRetry(error, attempt, maxRetries, retryOn) {
1125
+ if (attempt >= maxRetries) {
1126
+ return false;
1127
+ }
1128
+ if (this.cfg.retry?.retryOnError) {
1129
+ return this.cfg.retry.retryOnError(error);
1130
+ }
1131
+ if (error instanceof FetchError) {
1132
+ return retryOn.includes(error.status);
1133
+ }
1134
+ return true;
1135
+ }
171
1136
  };
172
1137
 
173
- // src/schema.ts
174
- var schema_exports = {};
1138
+ // src/client.ts
1139
+ var CoreClient = class extends FetchClient {
1140
+ constructor(cfg = {}) {
1141
+ const authStrategies = [];
1142
+ const { auth: _existingAuth, bearer, ...restCfg } = cfg;
1143
+ if (cfg.bearer) {
1144
+ const bearerValue = cfg.bearer;
1145
+ if (typeof bearerValue === "string") {
1146
+ authStrategies.push({
1147
+ type: "bearer",
1148
+ token: () => bearerValue
1149
+ });
1150
+ } else if (typeof bearerValue === "function") {
1151
+ authStrategies.push({
1152
+ type: "bearer",
1153
+ token: bearerValue
1154
+ });
1155
+ }
1156
+ }
1157
+ const finalAuthStrategies = [
1158
+ ..._existingAuth?.strategies || [],
1159
+ ...authStrategies
1160
+ ];
1161
+ const fetchConfig = {
1162
+ ...restCfg,
1163
+ baseURL: cfg.baseURL ?? "https://api.blimu.dev",
1164
+ // Explicitly set auth after restCfg to ensure it's not overwritten
1165
+ // (restCfg might have an auth property that we want to replace)
1166
+ ...finalAuthStrategies.length > 0 ? {
1167
+ auth: {
1168
+ strategies: finalAuthStrategies
1169
+ }
1170
+ } : {}
1171
+ // Hooks are passed through directly from FetchClientConfig (no mapping needed)
1172
+ };
1173
+ super(fetchConfig);
1174
+ }
1175
+ async request(init) {
1176
+ return await super.request(init);
1177
+ }
1178
+ async *requestStream(init) {
1179
+ yield* super.requestStream(init);
1180
+ }
1181
+ };
175
1182
 
176
1183
  // src/services/auth.ts
177
1184
  var AuthService = class {
@@ -179,9 +1186,8 @@ var AuthService = class {
179
1186
  this.core = core;
180
1187
  }
181
1188
  /**
182
- * POST /v1/auth/logout
183
- * @summary Logout and invalidate session
184
- */
1189
+ * POST /v1/auth/logout*
1190
+ * @summary Logout and invalidate session*/
185
1191
  logout(init) {
186
1192
  return this.core.request({
187
1193
  method: "POST",
@@ -197,9 +1203,8 @@ var AuthService = class {
197
1203
  return ["v1/auth/logout"];
198
1204
  }
199
1205
  /**
200
- * POST /v1/auth/refresh
201
- * @summary Refresh session token
202
- */
1206
+ * POST /v1/auth/refresh*
1207
+ * @summary Refresh session token*/
203
1208
  refresh(query, init) {
204
1209
  return this.core.request({
205
1210
  method: "POST",
@@ -216,9 +1221,8 @@ var AuthService = class {
216
1221
  return ["v1/auth/refresh", query];
217
1222
  }
218
1223
  /**
219
- * GET /v1/auth/session
220
- * @summary Get current session
221
- */
1224
+ * GET /v1/auth/session*
1225
+ * @summary Get current session*/
222
1226
  getSession(init) {
223
1227
  return this.core.request({
224
1228
  method: "GET",
@@ -241,11 +1245,9 @@ var EntitlementsService = class {
241
1245
  this.core = core;
242
1246
  }
243
1247
  /**
244
- * GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}
245
- * @summary List entitlements for a tenant and all its sub-resources
246
- *
247
- * @description Returns entitlements for a tenant resource and all its descendant resources for the authenticated user. This endpoint scopes queries to a single tenant, preventing cross-tenant data access. Only evaluates roles and plans (excludes limits). Results are cached per resource for performance. The tenant resource type is automatically determined from the environment definition (resource marked as `is_tenant: true`).
248
- */
1248
+ * GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}*
1249
+ * @summary List entitlements for a tenant and all its sub-resources*
1250
+ * @description Returns entitlements for a tenant resource and all its descendant resources for the authenticated user. This endpoint scopes queries to a single tenant, preventing cross-tenant data access. Only evaluates roles and plans (excludes limits). Results are cached per resource for performance. The tenant resource type is automatically determined from the environment definition (resource marked as `is_tenant: true`).*/
249
1251
  listForTenant(tenantResourceId, init) {
250
1252
  return this.core.request({
251
1253
  method: "GET",
@@ -258,7 +1260,10 @@ var EntitlementsService = class {
258
1260
  * @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]
259
1261
  */
260
1262
  listForTenant__queryKeys(tenantResourceId) {
261
- return ["v1/client/entitlements/list-for-tenant", tenantResourceId];
1263
+ return [
1264
+ "v1/client/entitlements/list-for-tenant",
1265
+ tenantResourceId
1266
+ ];
262
1267
  }
263
1268
  };
264
1269
 
@@ -279,14 +1284,64 @@ async function* paginate(fetchPage, initialQuery = {}, pageSize = 100) {
279
1284
  }
280
1285
  async function listAll(fetchPage, query = {}, pageSize = 100) {
281
1286
  const out = [];
282
- for await (const item of paginate(fetchPage, query, pageSize)) out.push(item);
1287
+ for await (const item of paginate(fetchPage, query, pageSize))
1288
+ out.push(item);
283
1289
  return out;
284
1290
  }
285
1291
 
1292
+ // src/schema.ts
1293
+ var schema_exports = {};
1294
+
1295
+ // src/schema.zod.ts
1296
+ var schema_zod_exports = {};
1297
+ __export(schema_zod_exports, {
1298
+ AuthRefreshQuerySchema: () => AuthRefreshQuerySchema,
1299
+ EntitlementTypeSchema: () => EntitlementTypeSchema,
1300
+ EntitlementsListResultSchema: () => EntitlementsListResultSchema,
1301
+ RefreshResponseSchema: () => RefreshResponseSchema,
1302
+ ResourceTypeSchema: () => ResourceTypeSchema,
1303
+ SessionResponseSchema: () => SessionResponseSchema
1304
+ });
1305
+ var import_zod = require("zod");
1306
+ var EntitlementTypeSchema = import_zod.z.string();
1307
+ var ResourceTypeSchema = import_zod.z.string();
1308
+ var EntitlementsListResultSchema = import_zod.z.object({
1309
+ results: import_zod.z.array(
1310
+ import_zod.z.object({
1311
+ entitlements: import_zod.z.array(
1312
+ import_zod.z.object({
1313
+ allowed: import_zod.z.boolean(),
1314
+ allowedByPlan: import_zod.z.boolean(),
1315
+ allowedByRole: import_zod.z.boolean(),
1316
+ allowedPlans: import_zod.z.array(import_zod.z.string()).optional(),
1317
+ allowedRoles: import_zod.z.array(import_zod.z.string()),
1318
+ currentPlan: import_zod.z.string().optional(),
1319
+ currentRole: import_zod.z.string().optional(),
1320
+ entitlement: EntitlementTypeSchema
1321
+ })
1322
+ ),
1323
+ resourceId: import_zod.z.string(),
1324
+ resourceType: ResourceTypeSchema
1325
+ })
1326
+ )
1327
+ });
1328
+ var RefreshResponseSchema = import_zod.z.object({ sessionToken: import_zod.z.string() });
1329
+ var SessionResponseSchema = import_zod.z.object({
1330
+ isAuthenticated: import_zod.z.boolean(),
1331
+ user: import_zod.z.object({
1332
+ email: import_zod.z.string(),
1333
+ emailVerified: import_zod.z.boolean(),
1334
+ firstName: import_zod.z.string().nullable(),
1335
+ id: import_zod.z.string(),
1336
+ lastName: import_zod.z.string().nullable()
1337
+ }).nullable()
1338
+ });
1339
+ var AuthRefreshQuerySchema = import_zod.z.object({
1340
+ __lh_jwt: import_zod.z.string().optional()
1341
+ });
1342
+
286
1343
  // src/index.ts
287
1344
  var Blimu = class {
288
- auth;
289
- entitlements;
290
1345
  constructor(options) {
291
1346
  const core = new CoreClient(options);
292
1347
  this.auth = new AuthService(core);
@@ -297,11 +1352,50 @@ var BlimuError = FetchError;
297
1352
  // Annotate the CommonJS export names for ESM import in node:
298
1353
  0 && (module.exports = {
299
1354
  AuthService,
1355
+ BadGatewayError,
1356
+ BadRequestError,
300
1357
  Blimu,
301
1358
  BlimuError,
1359
+ ClientError,
1360
+ ConflictError,
1361
+ CoreClient,
302
1362
  EntitlementsService,
1363
+ FetchClient,
303
1364
  FetchError,
1365
+ ForbiddenError,
1366
+ GatewayTimeoutError,
1367
+ HookRegistry,
1368
+ InternalServerError,
1369
+ MethodNotAllowedError,
1370
+ NotFoundError,
304
1371
  Schema,
1372
+ ServerError,
1373
+ ServiceUnavailableError,
1374
+ TooManyRequestsError,
1375
+ UnauthorizedError,
1376
+ UnprocessableEntityError,
1377
+ ZodSchema,
1378
+ buildUrl,
1379
+ calculateRetryDelay,
1380
+ createFetchError,
1381
+ encodeBase64,
1382
+ exponentialStrategy,
1383
+ getContentType,
1384
+ getFetchErrorMessage,
1385
+ getRetryStrategy,
1386
+ isAbortControllerAvailable,
1387
+ isBrowser,
1388
+ isFetchAvailable,
1389
+ isNode,
1390
+ isSuccessResponse,
1391
+ linearStrategy,
305
1392
  listAll,
306
- paginate
1393
+ paginate,
1394
+ parseChunkedStream,
1395
+ parseNDJSONStream,
1396
+ parseResponse,
1397
+ parseSSEStream,
1398
+ serializeBody,
1399
+ serializeQueryParams
307
1400
  });
1401
+ //# sourceMappingURL=index.js.map