@blimu/client 1.1.0 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -26
- package/dist/__tests__/example.test.cjs +17135 -0
- package/dist/__tests__/example.test.cjs.map +1 -0
- package/dist/__tests__/example.test.d.mts +2 -0
- package/dist/__tests__/example.test.d.ts +2 -0
- package/dist/__tests__/example.test.mjs +17134 -0
- package/dist/__tests__/example.test.mjs.map +1 -0
- package/dist/auth-strategies.cjs +40 -0
- package/dist/auth-strategies.cjs.map +1 -0
- package/dist/auth-strategies.d.mts +9 -0
- package/dist/auth-strategies.d.ts +9 -0
- package/dist/auth-strategies.mjs +15 -0
- package/dist/auth-strategies.mjs.map +1 -0
- package/dist/{client.js → client.cjs} +159 -66
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.mts +12 -18
- package/dist/client.d.ts +12 -18
- package/dist/client.mjs +155 -64
- package/dist/client.mjs.map +1 -1
- package/dist/{index.js → index.cjs} +115 -132
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +6 -19
- package/dist/index.d.ts +6 -19
- package/dist/index.mjs +112 -130
- package/dist/index.mjs.map +1 -1
- package/dist/{schema-B4iFbKly.d.mts → schema-Z0doltxY.d.mts} +8 -10
- package/dist/{schema-B4iFbKly.d.ts → schema-Z0doltxY.d.ts} +8 -10
- package/dist/{schema.js → schema.cjs} +2 -1
- package/dist/schema.cjs.map +1 -0
- package/dist/schema.d.mts +1 -2
- package/dist/schema.d.ts +1 -2
- package/dist/{schema.zod-CyY7RTSY.d.mts → schema.zod-BaQz36Pd.d.mts} +2 -6
- package/dist/{schema.zod-CyY7RTSY.d.ts → schema.zod-BaQz36Pd.d.ts} +2 -6
- package/dist/{schema.zod.js → schema.zod.cjs} +16 -25
- package/dist/schema.zod.cjs.map +1 -0
- package/dist/schema.zod.d.mts +1 -1
- package/dist/schema.zod.d.ts +1 -1
- package/dist/schema.zod.mjs +14 -22
- package/dist/schema.zod.mjs.map +1 -1
- package/dist/services/{auth.js → auth.cjs} +16 -5
- package/dist/services/auth.cjs.map +1 -0
- package/dist/services/auth.d.mts +6 -8
- package/dist/services/auth.d.ts +6 -8
- package/dist/services/auth.mjs +12 -4
- package/dist/services/auth.mjs.map +1 -1
- package/dist/services/{entitlements.js → entitlements.cjs} +4 -6
- package/dist/services/entitlements.cjs.map +1 -0
- package/dist/services/entitlements.d.mts +4 -6
- package/dist/services/entitlements.d.ts +4 -6
- package/dist/services/entitlements.mjs +2 -5
- package/dist/services/entitlements.mjs.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{utils.js → utils.cjs} +45 -26
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.mts +4 -3
- package/dist/utils.d.ts +4 -3
- package/dist/utils.mjs +42 -25
- package/dist/utils.mjs.map +1 -1
- package/package.json +32 -13
- package/dist/client.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/schema.zod.js.map +0 -1
- package/dist/services/auth.js.map +0 -1
- package/dist/services/entitlements.js.map +0 -1
- package/dist/utils.js.map +0 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/auth-strategies.ts
|
|
21
|
+
var auth_strategies_exports = {};
|
|
22
|
+
__export(auth_strategies_exports, {
|
|
23
|
+
buildAuthStrategies: () => buildAuthStrategies
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(auth_strategies_exports);
|
|
26
|
+
function buildAuthStrategies(cfg) {
|
|
27
|
+
const authStrategies = [...cfg?.authStrategies ?? []];
|
|
28
|
+
if (cfg.bearer) {
|
|
29
|
+
authStrategies.push({
|
|
30
|
+
type: "bearer",
|
|
31
|
+
token: cfg.bearer
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return authStrategies;
|
|
35
|
+
}
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
buildAuthStrategies
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=auth-strategies.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth-strategies.ts"],"sourcesContent":["import type { AuthStrategy } from '@blimu/fetch';\nimport type { ClientOption } from './client';\n\nexport function buildAuthStrategies(cfg: ClientOption): AuthStrategy[] {\n const authStrategies: AuthStrategy[] = [...(cfg?.authStrategies ?? [])];\n\n if (cfg.bearer) {\n authStrategies.push({\n type: 'bearer',\n token: cfg.bearer,\n });\n }\n return authStrategies;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,SAAS,oBAAoB,KAAmC;AACrE,QAAM,iBAAiC,CAAC,GAAI,KAAK,kBAAkB,CAAC,CAAE;AAEtE,MAAI,IAAI,QAAQ;AACd,mBAAe,KAAK;AAAA,MAClB,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AuthStrategy } from '@blimu/fetch';
|
|
2
|
+
import { ClientOption } from './client.mjs';
|
|
3
|
+
import './services/auth.mjs';
|
|
4
|
+
import './schema-Z0doltxY.mjs';
|
|
5
|
+
import './services/entitlements.mjs';
|
|
6
|
+
|
|
7
|
+
declare function buildAuthStrategies(cfg: ClientOption): AuthStrategy[];
|
|
8
|
+
|
|
9
|
+
export { buildAuthStrategies };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AuthStrategy } from '@blimu/fetch';
|
|
2
|
+
import { ClientOption } from './client.js';
|
|
3
|
+
import './services/auth.js';
|
|
4
|
+
import './schema-Z0doltxY.js';
|
|
5
|
+
import './services/entitlements.js';
|
|
6
|
+
|
|
7
|
+
declare function buildAuthStrategies(cfg: ClientOption): AuthStrategy[];
|
|
8
|
+
|
|
9
|
+
export { buildAuthStrategies };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/auth-strategies.ts
|
|
2
|
+
function buildAuthStrategies(cfg) {
|
|
3
|
+
const authStrategies = [...cfg?.authStrategies ?? []];
|
|
4
|
+
if (cfg.bearer) {
|
|
5
|
+
authStrategies.push({
|
|
6
|
+
type: "bearer",
|
|
7
|
+
token: cfg.bearer
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
return authStrategies;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
buildAuthStrategies
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=auth-strategies.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/auth-strategies.ts"],"sourcesContent":["import type { AuthStrategy } from '@blimu/fetch';\nimport type { ClientOption } from './client';\n\nexport function buildAuthStrategies(cfg: ClientOption): AuthStrategy[] {\n const authStrategies: AuthStrategy[] = [...(cfg?.authStrategies ?? [])];\n\n if (cfg.bearer) {\n authStrategies.push({\n type: 'bearer',\n token: cfg.bearer,\n });\n }\n return authStrategies;\n}\n"],"mappings":";AAGO,SAAS,oBAAoB,KAAmC;AACrE,QAAM,iBAAiC,CAAC,GAAI,KAAK,kBAAkB,CAAC,CAAE;AAEtE,MAAI,IAAI,QAAQ;AACd,mBAAe,KAAK;AAAA,MAClB,MAAM;AAAA,MACN,OAAO,IAAI;AAAA,IACb,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
var __defProp = Object.defineProperty;
|
|
2
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -19,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
20
|
// src/client.ts
|
|
20
21
|
var client_exports = {};
|
|
21
22
|
__export(client_exports, {
|
|
22
|
-
|
|
23
|
+
Blimu: () => Blimu,
|
|
24
|
+
BlimuError: () => BlimuError,
|
|
23
25
|
FetchError: () => FetchError
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(client_exports);
|
|
@@ -262,7 +264,7 @@ var HookRegistry = class {
|
|
|
262
264
|
if (!this.hooks.has(stage)) {
|
|
263
265
|
this.hooks.set(stage, []);
|
|
264
266
|
}
|
|
265
|
-
this.hooks.get(stage)
|
|
267
|
+
this.hooks.get(stage)?.push(hook);
|
|
266
268
|
}
|
|
267
269
|
/**
|
|
268
270
|
* Remove a specific hook from a stage
|
|
@@ -308,7 +310,14 @@ var HookRegistry = class {
|
|
|
308
310
|
* Check if any hooks are registered for a stage
|
|
309
311
|
*/
|
|
310
312
|
has(stage) {
|
|
311
|
-
|
|
313
|
+
if (!this.hooks.has(stage)) {
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
const hooks = this.hooks.get(stage);
|
|
317
|
+
if (!hooks) {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
return hooks.length > 0;
|
|
312
321
|
}
|
|
313
322
|
};
|
|
314
323
|
var exponentialStrategy = /* @__PURE__ */ __name((attempt, baseBackoffMs) => {
|
|
@@ -423,7 +432,7 @@ async function* parseNDJSONStream(response) {
|
|
|
423
432
|
try {
|
|
424
433
|
const parsed = JSON.parse(trimmed);
|
|
425
434
|
yield parsed;
|
|
426
|
-
} catch
|
|
435
|
+
} catch {
|
|
427
436
|
console.warn("Skipping invalid JSON line:", trimmed);
|
|
428
437
|
}
|
|
429
438
|
}
|
|
@@ -432,7 +441,7 @@ async function* parseNDJSONStream(response) {
|
|
|
432
441
|
try {
|
|
433
442
|
const parsed = JSON.parse(buffer.trim());
|
|
434
443
|
yield parsed;
|
|
435
|
-
} catch
|
|
444
|
+
} catch {
|
|
436
445
|
console.warn("Skipping invalid JSON in buffer:", buffer.trim());
|
|
437
446
|
}
|
|
438
447
|
}
|
|
@@ -637,19 +646,17 @@ var FetchClient = class {
|
|
|
637
646
|
* Add an authentication strategy
|
|
638
647
|
*/
|
|
639
648
|
addAuthStrategy(strategy) {
|
|
640
|
-
if (!this.cfg.
|
|
641
|
-
this.cfg.
|
|
642
|
-
strategies: []
|
|
643
|
-
};
|
|
649
|
+
if (!this.cfg.authStrategies) {
|
|
650
|
+
this.cfg.authStrategies = [];
|
|
644
651
|
}
|
|
645
|
-
this.cfg.
|
|
652
|
+
this.cfg.authStrategies.push(strategy);
|
|
646
653
|
}
|
|
647
654
|
/**
|
|
648
655
|
* Remove all authentication strategies
|
|
649
656
|
*/
|
|
650
657
|
clearAuthStrategies() {
|
|
651
|
-
if (this.cfg.
|
|
652
|
-
this.cfg.
|
|
658
|
+
if (this.cfg.authStrategies) {
|
|
659
|
+
this.cfg.authStrategies = [];
|
|
653
660
|
}
|
|
654
661
|
}
|
|
655
662
|
/**
|
|
@@ -673,8 +680,9 @@ var FetchClient = class {
|
|
|
673
680
|
/**
|
|
674
681
|
* Make an HTTP request
|
|
675
682
|
*/
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
676
684
|
async request(init) {
|
|
677
|
-
|
|
685
|
+
const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
678
686
|
const headers = new Headers(this.cfg.headers || {});
|
|
679
687
|
if (init.headers) {
|
|
680
688
|
if (init.headers instanceof Headers) {
|
|
@@ -711,7 +719,7 @@ var FetchClient = class {
|
|
|
711
719
|
let lastError;
|
|
712
720
|
for (let attempt = 0; attempt <= retries + 1; attempt++) {
|
|
713
721
|
try {
|
|
714
|
-
|
|
722
|
+
const attemptUrl = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
715
723
|
const attemptHeaders = new Headers(headers);
|
|
716
724
|
await this.applyAuthentication(attemptHeaders, attemptUrl);
|
|
717
725
|
return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType);
|
|
@@ -720,11 +728,13 @@ var FetchClient = class {
|
|
|
720
728
|
const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);
|
|
721
729
|
if (shouldRetry) {
|
|
722
730
|
if (this.hookRegistry.has("beforeRetry")) {
|
|
731
|
+
const serializedBody = serializeBody(init.body, bodyContentType);
|
|
723
732
|
await this.hookRegistry.execute("beforeRetry", {
|
|
724
733
|
url: url.toString(),
|
|
725
734
|
init: {
|
|
726
735
|
...init,
|
|
727
|
-
headers
|
|
736
|
+
headers,
|
|
737
|
+
body: serializedBody
|
|
728
738
|
},
|
|
729
739
|
attempt,
|
|
730
740
|
error: err,
|
|
@@ -734,11 +744,13 @@ var FetchClient = class {
|
|
|
734
744
|
const delay = calculateRetryDelay(attempt, retryStrategy, baseBackoff);
|
|
735
745
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
736
746
|
if (this.hookRegistry.has("afterRetry")) {
|
|
747
|
+
const serializedBody = serializeBody(init.body, bodyContentType);
|
|
737
748
|
await this.hookRegistry.execute("afterRetry", {
|
|
738
749
|
url: url.toString(),
|
|
739
750
|
init: {
|
|
740
751
|
...init,
|
|
741
|
-
headers
|
|
752
|
+
headers,
|
|
753
|
+
body: serializedBody
|
|
742
754
|
},
|
|
743
755
|
attempt,
|
|
744
756
|
error: err,
|
|
@@ -757,7 +769,7 @@ var FetchClient = class {
|
|
|
757
769
|
* Make a streaming HTTP request
|
|
758
770
|
*/
|
|
759
771
|
async *requestStream(init) {
|
|
760
|
-
|
|
772
|
+
const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
|
|
761
773
|
const headers = new Headers(this.cfg.headers || {});
|
|
762
774
|
if (init.headers) {
|
|
763
775
|
if (init.headers instanceof Headers) {
|
|
@@ -831,7 +843,8 @@ var FetchClient = class {
|
|
|
831
843
|
}
|
|
832
844
|
if (!res.ok) {
|
|
833
845
|
const parsed = await parseResponse(res);
|
|
834
|
-
const
|
|
846
|
+
const message = parsed?.message;
|
|
847
|
+
const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
|
|
835
848
|
if (this.hookRegistry.has("onError")) {
|
|
836
849
|
await this.hookRegistry.execute("onError", {
|
|
837
850
|
url: url.toString(),
|
|
@@ -853,7 +866,7 @@ var FetchClient = class {
|
|
|
853
866
|
const streamingFormat = init.streamingFormat || "chunked";
|
|
854
867
|
if (streamingFormat === "sse") {
|
|
855
868
|
for await (const chunk of parseSSEStream(res)) {
|
|
856
|
-
|
|
869
|
+
const transformedChunk = chunk;
|
|
857
870
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
858
871
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
859
872
|
url: url.toString(),
|
|
@@ -866,7 +879,7 @@ var FetchClient = class {
|
|
|
866
879
|
}
|
|
867
880
|
} else if (streamingFormat === "ndjson") {
|
|
868
881
|
for await (const chunk of parseNDJSONStream(res)) {
|
|
869
|
-
|
|
882
|
+
const transformedChunk = chunk;
|
|
870
883
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
871
884
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
872
885
|
url: url.toString(),
|
|
@@ -879,7 +892,7 @@ var FetchClient = class {
|
|
|
879
892
|
}
|
|
880
893
|
} else {
|
|
881
894
|
for await (const chunk of parseChunkedStream(res)) {
|
|
882
|
-
|
|
895
|
+
const transformedChunk = chunk;
|
|
883
896
|
if (this.hookRegistry.has("onStreamChunk")) {
|
|
884
897
|
await this.hookRegistry.execute("onStreamChunk", {
|
|
885
898
|
url: url.toString(),
|
|
@@ -984,7 +997,8 @@ var FetchClient = class {
|
|
|
984
997
|
});
|
|
985
998
|
}
|
|
986
999
|
if (!isSuccessResponse(res)) {
|
|
987
|
-
const
|
|
1000
|
+
const message = parsed?.message;
|
|
1001
|
+
const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
|
|
988
1002
|
if (this.hookRegistry.has("onError")) {
|
|
989
1003
|
await this.hookRegistry.execute("onError", {
|
|
990
1004
|
url: url.toString(),
|
|
@@ -1027,10 +1041,10 @@ var FetchClient = class {
|
|
|
1027
1041
|
* Apply authentication strategies
|
|
1028
1042
|
*/
|
|
1029
1043
|
async applyAuthentication(headers, url) {
|
|
1030
|
-
if (!this.cfg.
|
|
1044
|
+
if (!this.cfg.authStrategies) {
|
|
1031
1045
|
return;
|
|
1032
1046
|
}
|
|
1033
|
-
for (const strategy of this.cfg.
|
|
1047
|
+
for (const strategy of this.cfg.authStrategies) {
|
|
1034
1048
|
await this.applyAuthStrategy(strategy, headers, url);
|
|
1035
1049
|
}
|
|
1036
1050
|
}
|
|
@@ -1091,53 +1105,132 @@ var FetchClient = class {
|
|
|
1091
1105
|
}
|
|
1092
1106
|
};
|
|
1093
1107
|
|
|
1094
|
-
// src/
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
const fetchConfig = {
|
|
1118
|
-
...restCfg,
|
|
1119
|
-
baseURL: cfg.baseURL ?? "https://api.blimu.dev",
|
|
1120
|
-
// Explicitly set auth after restCfg to ensure it's not overwritten
|
|
1121
|
-
// (restCfg might have an auth property that we want to replace)
|
|
1122
|
-
...finalAuthStrategies.length > 0 ? {
|
|
1123
|
-
auth: {
|
|
1124
|
-
strategies: finalAuthStrategies
|
|
1125
|
-
}
|
|
1126
|
-
} : {}
|
|
1127
|
-
// Hooks are passed through directly from FetchClientConfig (no mapping needed)
|
|
1128
|
-
};
|
|
1129
|
-
super(fetchConfig);
|
|
1108
|
+
// src/auth-strategies.ts
|
|
1109
|
+
function buildAuthStrategies(cfg) {
|
|
1110
|
+
const authStrategies = [...cfg?.authStrategies ?? []];
|
|
1111
|
+
if (cfg.bearer) {
|
|
1112
|
+
authStrategies.push({
|
|
1113
|
+
type: "bearer",
|
|
1114
|
+
token: cfg.bearer
|
|
1115
|
+
});
|
|
1116
|
+
}
|
|
1117
|
+
return authStrategies;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// src/utils.ts
|
|
1121
|
+
function isNotUndefined(arr) {
|
|
1122
|
+
return arr.filter(
|
|
1123
|
+
(item) => item !== void 0
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// src/services/auth.ts
|
|
1128
|
+
var AuthService = class {
|
|
1129
|
+
constructor(core) {
|
|
1130
|
+
this.core = core;
|
|
1130
1131
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1132
|
+
/**
|
|
1133
|
+
* POST /v1/auth/logout*
|
|
1134
|
+
* @summary Logout and invalidate session*/
|
|
1135
|
+
logout(init) {
|
|
1136
|
+
return this.core.request({
|
|
1137
|
+
method: "POST",
|
|
1138
|
+
path: `/v1/auth/logout`,
|
|
1139
|
+
...init ?? {}
|
|
1140
|
+
});
|
|
1133
1141
|
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1142
|
+
/**
|
|
1143
|
+
* @summary Get query keys for logout
|
|
1144
|
+
* @returns ['v1/auth/logout']
|
|
1145
|
+
*/
|
|
1146
|
+
logout__queryKeys() {
|
|
1147
|
+
return ["v1/auth/logout"];
|
|
1148
|
+
}
|
|
1149
|
+
/**
|
|
1150
|
+
* POST /v1/auth/refresh*
|
|
1151
|
+
* @summary Refresh session token*/
|
|
1152
|
+
refresh(query, init) {
|
|
1153
|
+
return this.core.request({
|
|
1154
|
+
method: "POST",
|
|
1155
|
+
path: `/v1/auth/refresh`,
|
|
1156
|
+
query,
|
|
1157
|
+
...init ?? {}
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* @summary Get query keys for refresh
|
|
1162
|
+
* @returns ['v1/auth/refresh', query]
|
|
1163
|
+
*/
|
|
1164
|
+
refresh__queryKeys(query) {
|
|
1165
|
+
const keys = ["v1/auth/refresh", query];
|
|
1166
|
+
return isNotUndefined(keys);
|
|
1167
|
+
}
|
|
1168
|
+
/**
|
|
1169
|
+
* GET /v1/auth/session*
|
|
1170
|
+
* @summary Get current session*/
|
|
1171
|
+
getSession(init) {
|
|
1172
|
+
return this.core.request({
|
|
1173
|
+
method: "GET",
|
|
1174
|
+
path: `/v1/auth/session`,
|
|
1175
|
+
...init ?? {}
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* @summary Get query keys for getSession
|
|
1180
|
+
* @returns ['v1/auth/session']
|
|
1181
|
+
*/
|
|
1182
|
+
getSession__queryKeys() {
|
|
1183
|
+
return ["v1/auth/session"];
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
// src/services/entitlements.ts
|
|
1188
|
+
var EntitlementsService = class {
|
|
1189
|
+
constructor(core) {
|
|
1190
|
+
this.core = core;
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1193
|
+
* GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}*
|
|
1194
|
+
* @summary List entitlements for a tenant and all its sub-resources*
|
|
1195
|
+
* @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`).*/
|
|
1196
|
+
listForTenant(tenantResourceId, init) {
|
|
1197
|
+
return this.core.request({
|
|
1198
|
+
method: "GET",
|
|
1199
|
+
path: `/v1/client/entitlements/list-for-tenant/${encodeURIComponent(tenantResourceId)}`,
|
|
1200
|
+
...init ?? {}
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* @summary Get query keys for listForTenant
|
|
1205
|
+
* @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]
|
|
1206
|
+
*/
|
|
1207
|
+
listForTenant__queryKeys(tenantResourceId) {
|
|
1208
|
+
return ["v1/client/entitlements/list-for-tenant", tenantResourceId];
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
// src/client.ts
|
|
1213
|
+
var Blimu = class {
|
|
1214
|
+
auth;
|
|
1215
|
+
entitlements;
|
|
1216
|
+
constructor(options) {
|
|
1217
|
+
const restCfg = { ...options ?? {} };
|
|
1218
|
+
delete restCfg.bearer;
|
|
1219
|
+
const authStrategies = buildAuthStrategies(options ?? {});
|
|
1220
|
+
const core = new FetchClient({
|
|
1221
|
+
...restCfg,
|
|
1222
|
+
baseURL: options?.baseURL ?? "https://api.blimu.dev",
|
|
1223
|
+
...authStrategies.length > 0 ? { authStrategies } : {}
|
|
1224
|
+
});
|
|
1225
|
+
this.auth = new AuthService(core);
|
|
1226
|
+
this.entitlements = new EntitlementsService(core);
|
|
1136
1227
|
}
|
|
1137
1228
|
};
|
|
1229
|
+
var BlimuError = FetchError;
|
|
1138
1230
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1139
1231
|
0 && (module.exports = {
|
|
1140
|
-
|
|
1232
|
+
Blimu,
|
|
1233
|
+
BlimuError,
|
|
1141
1234
|
FetchError
|
|
1142
1235
|
});
|
|
1143
|
-
//# sourceMappingURL=client.
|
|
1236
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../../../node_modules/@blimu/fetch/src/errors.ts","../../../node_modules/@blimu/fetch/src/hooks/registry.ts","../../../node_modules/@blimu/fetch/src/retry/strategies.ts","../../../node_modules/@blimu/fetch/src/streaming/parsers.ts","../../../node_modules/@blimu/fetch/src/utils/environment.ts","../../../node_modules/@blimu/fetch/src/utils/request.ts","../../../node_modules/@blimu/fetch/src/utils/response.ts","../../../node_modules/@blimu/fetch/src/client.ts","../src/auth-strategies.ts","../src/utils.ts","../src/services/auth.ts","../src/services/entitlements.ts"],"sourcesContent":["import { FetchClient, FetchError } from '@blimu/fetch';\nimport { type FetchClientConfig, type BearerAuthStrategy } from '@blimu/fetch';\nimport { buildAuthStrategies } from './auth-strategies';\nimport { AuthService } from './services/auth';\nimport { EntitlementsService } from './services/entitlements';\n\nexport type ClientOption = FetchClientConfig & {\n bearer?: BearerAuthStrategy['token'];\n};\n\nexport class Blimu {\n readonly auth: AuthService;\n readonly entitlements: EntitlementsService;\n\n constructor(options?: ClientOption) {\n const restCfg = { ...(options ?? {}) };\n delete restCfg.bearer;\n\n const authStrategies = buildAuthStrategies(options ?? {});\n\n const core = new FetchClient({\n ...restCfg,\n baseURL: options?.baseURL ?? 'https://api.blimu.dev',\n ...(authStrategies.length > 0 ? { authStrategies } : {}),\n });\n\n this.auth = new AuthService(core);\n this.entitlements = new EntitlementsService(core);\n }\n}\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\nexport const BlimuError = FetchError;\n","/**\n * Base error class for all fetch-related errors\n */\nexport class FetchError<T = unknown> extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly data?: T,\n public readonly headers?: Headers\n ) {\n super(message);\n this.name = 'FetchError';\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, FetchError);\n }\n }\n}\n\n/**\n * Base class for all 4xx client errors\n */\nexport class ClientError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ClientError';\n }\n}\n\n/**\n * Base class for all 5xx server errors\n */\nexport class ServerError<T = unknown> extends FetchError<T> {\n constructor(message: string, status: number, data?: T, headers?: Headers) {\n super(message, status, data, headers);\n this.name = 'ServerError';\n }\n}\n\n// 4xx Client Errors\nexport class BadRequestError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Bad Request', data?: T, headers?: Headers) {\n super(message, 400, data, headers);\n this.name = 'BadRequestError';\n }\n}\n\nexport class UnauthorizedError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Unauthorized', data?: T, headers?: Headers) {\n super(message, 401, data, headers);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class ForbiddenError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Forbidden', data?: T, headers?: Headers) {\n super(message, 403, data, headers);\n this.name = 'ForbiddenError';\n }\n}\n\nexport class NotFoundError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Not Found', data?: T, headers?: Headers) {\n super(message, 404, data, headers);\n this.name = 'NotFoundError';\n }\n}\n\nexport class MethodNotAllowedError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Method Not Allowed',\n data?: T,\n headers?: Headers\n ) {\n super(message, 405, data, headers);\n this.name = 'MethodNotAllowedError';\n }\n}\n\nexport class ConflictError<T = unknown> extends ClientError<T> {\n constructor(message: string = 'Conflict', data?: T, headers?: Headers) {\n super(message, 409, data, headers);\n this.name = 'ConflictError';\n }\n}\n\nexport class UnprocessableEntityError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Unprocessable Entity',\n data?: T,\n headers?: Headers\n ) {\n super(message, 422, data, headers);\n this.name = 'UnprocessableEntityError';\n }\n}\n\nexport class TooManyRequestsError<T = unknown> extends ClientError<T> {\n constructor(\n message: string = 'Too Many Requests',\n data?: T,\n headers?: Headers\n ) {\n super(message, 429, data, headers);\n this.name = 'TooManyRequestsError';\n }\n}\n\n// 5xx Server Errors\nexport class InternalServerError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Internal Server Error',\n data?: T,\n headers?: Headers\n ) {\n super(message, 500, data, headers);\n this.name = 'InternalServerError';\n }\n}\n\nexport class BadGatewayError<T = unknown> extends ServerError<T> {\n constructor(message: string = 'Bad Gateway', data?: T, headers?: Headers) {\n super(message, 502, data, headers);\n this.name = 'BadGatewayError';\n }\n}\n\nexport class ServiceUnavailableError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Service Unavailable',\n data?: T,\n headers?: Headers\n ) {\n super(message, 503, data, headers);\n this.name = 'ServiceUnavailableError';\n }\n}\n\nexport class GatewayTimeoutError<T = unknown> extends ServerError<T> {\n constructor(\n message: string = 'Gateway Timeout',\n data?: T,\n headers?: Headers\n ) {\n super(message, 504, data, headers);\n this.name = 'GatewayTimeoutError';\n }\n}\n\n/**\n * Factory function to create the appropriate error class based on status code\n */\nexport function createFetchError<T = unknown>(\n status: number,\n message?: string,\n data?: T,\n headers?: Headers\n): FetchError<T> {\n const defaultMessage = message || `HTTP ${status}`;\n\n // 4xx Client Errors\n switch (status) {\n case 400:\n return new BadRequestError(defaultMessage, data, headers);\n case 401:\n return new UnauthorizedError(defaultMessage, data, headers);\n case 403:\n return new ForbiddenError(defaultMessage, data, headers);\n case 404:\n return new NotFoundError(defaultMessage, data, headers);\n case 405:\n return new MethodNotAllowedError(defaultMessage, data, headers);\n case 409:\n return new ConflictError(defaultMessage, data, headers);\n case 422:\n return new UnprocessableEntityError(defaultMessage, data, headers);\n case 429:\n return new TooManyRequestsError(defaultMessage, data, headers);\n // Generic 4xx\n case 402:\n case 406:\n case 407:\n case 408:\n case 410:\n case 411:\n case 412:\n case 413:\n case 414:\n case 415:\n case 416:\n case 417:\n case 418:\n case 421:\n case 423:\n case 424:\n case 425:\n case 426:\n case 428:\n case 431:\n case 451:\n return new ClientError(defaultMessage, status, data, headers);\n\n // 5xx Server Errors\n case 500:\n return new InternalServerError(defaultMessage, data, headers);\n case 502:\n return new BadGatewayError(defaultMessage, data, headers);\n case 503:\n return new ServiceUnavailableError(defaultMessage, data, headers);\n case 504:\n return new GatewayTimeoutError(defaultMessage, data, headers);\n // Generic 5xx\n case 501:\n case 505:\n case 506:\n case 507:\n case 508:\n case 510:\n case 511:\n return new ServerError(defaultMessage, status, data, headers);\n\n default:\n // For any other status code, return base FetchError\n return new FetchError(defaultMessage, status, data, headers);\n }\n}\n","import type { Hook, HookContext, HookStage, HooksConfig } from './types';\n\n/**\n * Hook registry that manages hooks for different lifecycle stages\n */\nexport class HookRegistry {\n private hooks: Map<HookStage, Hook[]> = new Map();\n\n constructor(config?: HooksConfig) {\n if (config) {\n this.registerFromConfig(config);\n }\n }\n\n /**\n * Register hooks from a configuration object\n */\n registerFromConfig(config: HooksConfig): void {\n for (const [stage, hooks] of Object.entries(config)) {\n if (hooks && Array.isArray(hooks)) {\n for (const hook of hooks) {\n this.register(stage as HookStage, hook);\n }\n }\n }\n }\n\n /**\n * Register a hook for a specific stage\n */\n register(stage: HookStage, hook: Hook): void {\n if (!this.hooks.has(stage)) {\n this.hooks.set(stage, []);\n }\n\n this.hooks.get(stage)?.push(hook);\n }\n\n /**\n * Remove a specific hook from a stage\n */\n remove(stage: HookStage, hook: Hook): boolean {\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n\n const index = hooks.indexOf(hook);\n if (index === -1) {\n return false;\n }\n\n hooks.splice(index, 1);\n return true;\n }\n\n /**\n * Clear all hooks for a specific stage, or all hooks if no stage is provided\n */\n clear(stage?: HookStage): void {\n if (stage) {\n this.hooks.delete(stage);\n } else {\n this.hooks.clear();\n }\n }\n\n /**\n * Get all hooks for a specific stage\n */\n get(stage: HookStage): Hook[] {\n return this.hooks.get(stage) || [];\n }\n\n /**\n * Execute all hooks for a specific stage in registration order\n */\n async execute(stage: HookStage, context: HookContext): Promise<void> {\n const hooks = this.get(stage);\n for (const hook of hooks) {\n await hook(context);\n }\n }\n\n /**\n * Check if any hooks are registered for a stage\n */\n has(stage: HookStage): boolean {\n if (!this.hooks.has(stage)) {\n return false;\n }\n const hooks = this.hooks.get(stage);\n if (!hooks) {\n return false;\n }\n return hooks.length > 0;\n }\n}\n","import type { RetryStrategyFunction } from './types';\n\n/**\n * Exponential backoff strategy\n * Delay = baseBackoffMs * 2^attempt\n */\nexport const exponentialStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * Math.pow(2, attempt);\n};\n\n/**\n * Linear backoff strategy\n * Delay = baseBackoffMs * (attempt + 1)\n */\nexport const linearStrategy: RetryStrategyFunction = (\n attempt: number,\n baseBackoffMs: number\n): number => {\n return baseBackoffMs * (attempt + 1);\n};\n\n/**\n * Get the retry strategy function based on the strategy name or function\n */\nexport function getRetryStrategy(\n strategy: 'exponential' | 'linear' | RetryStrategyFunction\n): RetryStrategyFunction {\n if (typeof strategy === 'function') {\n return strategy;\n }\n\n switch (strategy) {\n case 'exponential':\n return exponentialStrategy;\n case 'linear':\n return linearStrategy;\n default:\n return exponentialStrategy;\n }\n}\n\n/**\n * Calculate the delay for a retry attempt\n */\nexport function calculateRetryDelay(\n attempt: number,\n strategy: 'exponential' | 'linear' | RetryStrategyFunction,\n baseBackoffMs: number\n): number {\n const strategyFn = getRetryStrategy(strategy);\n return strategyFn(attempt, baseBackoffMs);\n}\n","/**\n * Parse Server-Sent Events (SSE) stream\n * Extracts data fields from text/event-stream format\n */\nexport async function* parseSSEStream(\n response: Response\n): AsyncGenerator<string, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n let currentEvent: { type?: string; data?: string; id?: string } = {};\n\n for (const line of lines) {\n if (line.trim() === '') {\n // Empty line indicates end of event\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n currentEvent = {};\n continue;\n }\n\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n } else if (field === 'event') {\n currentEvent.type = value;\n } else if (field === 'id') {\n currentEvent.id = value;\n }\n }\n }\n\n // Handle any remaining event in buffer\n if (buffer.trim()) {\n const lines = buffer.split('\\n');\n let currentEvent: { data?: string } = {};\n for (const line of lines) {\n if (line.trim() === '' && currentEvent.data !== undefined) {\n yield currentEvent.data;\n currentEvent = {};\n continue;\n }\n const colonIndex = line.indexOf(':');\n if (colonIndex !== -1) {\n const field = line.substring(0, colonIndex).trim();\n const value = line.substring(colonIndex + 1).trim();\n if (field === 'data') {\n currentEvent.data = currentEvent.data\n ? currentEvent.data + '\\n' + value\n : value;\n }\n }\n }\n if (currentEvent.data !== undefined) {\n yield currentEvent.data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\ntype AnyParsedNDJSON = string | object | ArrayBuffer | unknown;\n\n/**\n * Parse NDJSON (Newline-Delimited JSON) stream\n * Yields each JSON object as it arrives\n */\nexport async function* parseNDJSONStream<T = AnyParsedNDJSON>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || ''; // Keep incomplete line in buffer\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed === '') continue;\n\n try {\n const parsed = JSON.parse(trimmed) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON lines\n console.warn('Skipping invalid JSON line:', trimmed);\n }\n }\n }\n\n // Handle any remaining line in buffer\n if (buffer.trim()) {\n try {\n const parsed = JSON.parse(buffer.trim()) as T;\n yield parsed;\n } catch {\n // Skip invalid JSON\n console.warn('Skipping invalid JSON in buffer:', buffer.trim());\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Parse generic chunked stream\n * Yields raw chunks as strings\n */\nexport async function* parseChunkedStream<T = string>(\n response: Response\n): AsyncGenerator<T, void, unknown> {\n if (!response.body) {\n return;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n yield chunk as T;\n }\n } finally {\n reader.releaseLock();\n }\n}\n","/**\n * Detects if the code is running in a browser environment\n */\nexport function isBrowser(): boolean {\n return (\n typeof globalThis !== 'undefined' &&\n typeof (globalThis as unknown as { window: unknown }).window !==\n 'undefined' &&\n typeof (globalThis as unknown as { window: { document: unknown } }).window\n .document !== 'undefined'\n );\n}\n\n/**\n * Detects if the code is running in a Node.js environment\n */\nexport function isNode(): boolean {\n return (\n typeof process !== 'undefined' &&\n process.versions != null &&\n process.versions.node != null\n );\n}\n\n/**\n * Encodes a string to Base64, using the appropriate method for the environment\n * @param str - String to encode\n * @returns Base64 encoded string\n */\nexport function encodeBase64(str: string): string {\n if (isBrowser()) {\n // Browser environment - use btoa\n if (typeof btoa !== 'undefined') {\n return btoa(str);\n }\n // Fallback for environments where btoa might not be available\n throw new Error(\n 'btoa is not available. This should not happen in a browser environment.'\n );\n } else {\n // Node.js environment - use Buffer\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n throw new Error(\n \"Buffer is not available. Please ensure you're running in Node.js or provide a polyfill.\"\n );\n }\n}\n\n/**\n * Checks if the native fetch API is available\n * @returns true if fetch is available, false otherwise\n */\nexport function isFetchAvailable(): boolean {\n return typeof fetch !== 'undefined';\n}\n\n/**\n * Checks if AbortController is available\n * @returns true if AbortController is available, false otherwise\n */\nexport function isAbortControllerAvailable(): boolean {\n return typeof AbortController !== 'undefined';\n}\n\n/**\n * Gets a helpful error message if fetch is not available\n * @returns Error message with suggestions\n */\nexport function getFetchErrorMessage(): string {\n if (isBrowser()) {\n return 'fetch is not available in this browser. Please use a modern browser or provide a polyfill.';\n } else {\n 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').\";\n }\n}\n","import type { QueryParams } from '../types';\n\n/**\n * Serializes query parameters into a URLSearchParams object\n * Handles arrays, objects, and primitive values\n */\nexport function serializeQueryParams(query: QueryParams): URLSearchParams {\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined || value === null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n // Append each array item\n for (const item of value) {\n if (item !== undefined && item !== null) {\n params.append(key, String(item));\n }\n }\n } else {\n params.set(key, String(value));\n }\n }\n\n return params;\n}\n\n/**\n * Builds a URL with query parameters\n * @param baseUrl - Base URL\n * @param path - Path to append\n * @param query - Query parameters object\n * @returns Complete URL with query string\n */\nexport function buildUrl(\n baseUrl: string,\n path: string,\n query?: QueryParams | undefined\n): URL {\n // Normalize path - remove trailing slash if present (except for root)\n let normalizedPath = path || '';\n if (normalizedPath.length > 1 && normalizedPath.endsWith('/')) {\n normalizedPath = normalizedPath.slice(0, -1);\n }\n\n // Normalize baseURL to ensure it has a trailing slash if it has a path component\n // This is needed because new URL('path', 'https://example.com/base') creates\n // 'https://example.com/path' (treats base as a file), but\n // new URL('path', 'https://example.com/base/') creates 'https://example.com/base/path' (correct)\n let normalizedBaseUrl = baseUrl || '';\n if (normalizedBaseUrl) {\n try {\n const baseUrlObj = new URL(normalizedBaseUrl);\n // If baseURL has a path component and doesn't end with /, add it\n if (\n baseUrlObj.pathname &&\n baseUrlObj.pathname !== '/' &&\n !normalizedBaseUrl.endsWith('/')\n ) {\n normalizedBaseUrl = normalizedBaseUrl + '/';\n }\n } catch {\n // If baseUrl is not a valid URL, proceed as-is\n }\n }\n\n // If path starts with /, strip it so it appends to baseURL instead of replacing it\n if (normalizedPath.startsWith('/')) {\n normalizedPath = normalizedPath.slice(1);\n }\n\n const url = new URL(normalizedPath, normalizedBaseUrl);\n\n if (query) {\n const params = serializeQueryParams(query);\n // Merge with existing search params\n // Get all unique keys first\n const keys = Array.from(new Set(params.keys()));\n for (const key of keys) {\n // Remove existing values for this key\n url.searchParams.delete(key);\n // Append all values (handles arrays correctly)\n for (const value of params.getAll(key)) {\n url.searchParams.append(key, value);\n }\n }\n }\n\n return url;\n}\n\n/**\n * Determines the content type from a body value\n * @param body - Request body\n * @returns Content type string or undefined\n */\nexport function getContentType(body: unknown): string | undefined {\n if (body === null || body === undefined) {\n return undefined;\n }\n\n if (body instanceof FormData) {\n // FormData sets its own content-type with boundary\n return undefined; // Let the browser set it\n }\n\n if (body instanceof URLSearchParams) {\n return 'application/x-www-form-urlencoded';\n }\n\n if (typeof body === 'string') {\n // Try to detect if it's JSON\n try {\n JSON.parse(body);\n return 'application/json';\n } catch {\n return 'text/plain';\n }\n }\n\n if (typeof body === 'object') {\n return 'application/json';\n }\n\n return undefined;\n}\n\n/**\n * Serializes a request body based on its type\n * @param body - Request body to serialize\n * @param contentType - Optional content type hint to guide serialization\n * @returns Serialized body (string, FormData, Blob, ArrayBuffer, etc.)\n */\nexport function serializeBody(\n body: unknown,\n contentType?: string\n): RequestInit['body'] | null {\n if (body === null || body === undefined) {\n return null;\n }\n\n // If it's already a valid body type, return as-is\n if (\n typeof body === 'string' ||\n body instanceof FormData ||\n body instanceof URLSearchParams ||\n body instanceof Blob ||\n body instanceof ArrayBuffer ||\n ArrayBuffer.isView(body)\n ) {\n return body as RequestInit['body'];\n }\n\n // Handle form-urlencoded: convert object to URLSearchParams\n if (\n contentType === 'application/x-www-form-urlencoded' &&\n typeof body === 'object' &&\n body !== null &&\n !Array.isArray(body)\n ) {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (value !== null && value !== undefined) {\n if (Array.isArray(value)) {\n // Handle array values (multiple params with same key)\n for (const item of value) {\n params.append(key, String(item));\n }\n } else {\n params.append(key, String(value));\n }\n }\n }\n return params;\n }\n\n // For objects, serialize to JSON (default)\n if (typeof body === 'object') {\n return JSON.stringify(body);\n }\n\n // For primitives, convert to string\n return String(body);\n}\n","/**\n * Parses a response based on its content type\n * @param response - Fetch Response object\n * @returns Parsed response data\n */\n\ntype AnyPromiseResponse = Promise<string | object | ArrayBuffer | unknown>;\n\nexport async function parseResponse(response: Response): AnyPromiseResponse {\n const contentType = response.headers.get('content-type') || '';\n\n if (contentType.includes('application/json')) {\n return await response.json();\n } else if (contentType.startsWith('text/')) {\n return await response.text();\n } else {\n // Binary or unknown content type - return ArrayBuffer\n return await response.arrayBuffer();\n }\n}\n\n/**\n * Checks if a response indicates success (status 200-299)\n * @param response - Fetch Response object\n * @returns true if response is successful\n */\nexport function isSuccessResponse(response: Response): boolean {\n return response.ok;\n}\n","import { createFetchError, FetchError } from './errors';\nimport { HookRegistry } from './hooks';\nimport type { Hook, HookStage } from './hooks/types';\nimport { calculateRetryDelay } from './retry';\nimport {\n parseSSEStream,\n parseNDJSONStream,\n parseChunkedStream,\n} from './streaming';\nimport type {\n FetchClientConfig,\n QueryParams,\n RequestOptions,\n StreamingRequestOptions,\n AuthStrategy,\n} from './types';\nimport {\n buildUrl,\n serializeBody,\n getContentType,\n parseResponse,\n isSuccessResponse,\n} from './utils';\nimport {\n isFetchAvailable,\n getFetchErrorMessage,\n encodeBase64,\n} from './utils/environment';\n\n/**\n * Universal HTTP fetch client with hooks, retries, and streaming support\n */\nexport class FetchClient {\n private hookRegistry: HookRegistry;\n private cfg: FetchClientConfig;\n\n constructor(config: FetchClientConfig = {}) {\n this.cfg = config;\n\n // Set default base URL if not provided\n if (!this.cfg.baseURL) {\n this.cfg.baseURL = '';\n }\n\n // Initialize hook registry\n this.hookRegistry = new HookRegistry(this.cfg.hooks);\n\n // Check fetch availability\n if (!isFetchAvailable() && !this.cfg.fetch) {\n throw new Error(getFetchErrorMessage());\n }\n }\n\n /**\n * Add an authentication strategy\n */\n addAuthStrategy(strategy: AuthStrategy): void {\n if (!this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n this.cfg.authStrategies.push(strategy);\n }\n\n /**\n * Remove all authentication strategies\n */\n clearAuthStrategies(): void {\n if (this.cfg.authStrategies) {\n this.cfg.authStrategies = [];\n }\n }\n\n /**\n * Register a hook for a specific lifecycle stage\n */\n useHook(stage: HookStage, hook: Hook): void {\n this.hookRegistry.register(stage, hook);\n }\n\n /**\n * Remove a hook\n */\n removeHook(stage: HookStage, hook: Hook): boolean {\n return this.hookRegistry.remove(stage, hook);\n }\n\n /**\n * Clear hooks for a stage or all hooks\n */\n clearHooks(stage?: HookStage): void {\n this.hookRegistry.clear(stage);\n }\n\n /**\n * Make an HTTP request\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async request<T = any>(init: RequestOptions): Promise<T> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Set content type if body is provided (check before serialization)\n let bodyContentType: string | undefined;\n if (init.body !== undefined) {\n // Check if Content-Type is already set in headers\n bodyContentType = headers.get('Content-Type') || undefined;\n if (!bodyContentType) {\n bodyContentType = getContentType(init.body);\n if (bodyContentType) {\n headers.set('Content-Type', bodyContentType);\n }\n }\n }\n\n const retries = this.cfg.retry?.retries ?? 0;\n const baseBackoff = this.cfg.retry?.backoffMs ?? 300;\n const retryOn = this.cfg.retry?.retryOn ?? [429, 500, 502, 503, 504];\n const retryStrategy = this.cfg.retry?.strategy ?? 'exponential';\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries + 1; attempt++) {\n try {\n // Rebuild URL for each attempt (in case query params were modified by auth)\n const attemptUrl = buildUrl(\n this.cfg.baseURL || '',\n init.path,\n init.query\n );\n // Clone headers for each attempt\n const attemptHeaders = new Headers(headers);\n // Re-apply authentication for each attempt\n await this.applyAuthentication(attemptHeaders, attemptUrl);\n return await this.doRequest<T>(\n attemptUrl,\n init,\n attemptHeaders,\n attempt,\n bodyContentType\n );\n } catch (err) {\n lastError = err;\n\n // Check if we should retry\n const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);\n\n if (shouldRetry) {\n // Execute beforeRetry hook\n if (this.hookRegistry.has('beforeRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('beforeRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n });\n }\n\n // Calculate delay\n const delay = calculateRetryDelay(\n attempt,\n retryStrategy,\n baseBackoff\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n\n // Execute afterRetry hook\n if (this.hookRegistry.has('afterRetry')) {\n const serializedBody = serializeBody(init.body, bodyContentType);\n await this.hookRegistry.execute('afterRetry', {\n url: url.toString(),\n init: { ...init, headers, body: serializedBody },\n attempt,\n error: err,\n retryCount: attempt,\n success: false, // Will be updated if retry succeeds\n });\n }\n\n continue;\n }\n\n // Not retrying - throw the error\n throw err;\n }\n }\n\n throw lastError as unknown;\n }\n\n /**\n * Make a streaming HTTP request\n */\n async *requestStream<T = unknown>(\n init: StreamingRequestOptions\n ): AsyncGenerator<T, void, unknown> {\n const url = buildUrl(this.cfg.baseURL || '', init.path, init.query);\n // Create headers, handling both plain objects and Headers instances\n const headers = new Headers(this.cfg.headers || {});\n if (init.headers) {\n if (init.headers instanceof Headers) {\n // Copy from Headers object\n init.headers.forEach((value, key) => {\n headers.set(key, value);\n });\n } else {\n // Merge from plain object\n Object.entries(init.headers).forEach(([key, value]) => {\n headers.set(key, String(value));\n });\n }\n }\n\n // Apply authentication (may modify URL for query-based auth)\n await this.applyAuthentication(headers, url);\n\n // Determine content type for body serialization\n let bodyContentType: string | undefined =\n headers.get('Content-Type') || undefined;\n if (init.contentType && !bodyContentType) {\n bodyContentType = init.contentType;\n headers.set('Content-Type', bodyContentType);\n }\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers,\n body: serializeBody(init.body, bodyContentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n if (!res.ok) {\n const parsed = await parseResponse(res);\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error,\n });\n }\n\n throw error;\n }\n\n // Execute onStreamStart hook\n if (this.hookRegistry.has('onStreamStart')) {\n await this.hookRegistry.execute('onStreamStart', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n\n // Route to appropriate parser based on streaming format\n const streamingFormat = init.streamingFormat || 'chunked';\n\n if (streamingFormat === 'sse') {\n for await (const chunk of parseSSEStream(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else if (streamingFormat === 'ndjson') {\n for await (const chunk of parseNDJSONStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n } else {\n // Generic chunked streaming\n for await (const chunk of parseChunkedStream<T>(res)) {\n const transformedChunk = chunk;\n // Execute onStreamChunk hook if present\n if (this.hookRegistry.has('onStreamChunk')) {\n await this.hookRegistry.execute('onStreamChunk', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n chunk,\n });\n }\n yield transformedChunk as T;\n }\n }\n\n // Execute onStreamEnd hook\n if (this.hookRegistry.has('onStreamEnd')) {\n await this.hookRegistry.execute('onStreamEnd', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n response: res,\n });\n }\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt: 0,\n error: err,\n });\n }\n throw err;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Internal method to execute a single request attempt\n */\n private async doRequest<T>(\n url: URL,\n init: RequestOptions,\n baseHeaders: Headers,\n attempt: number,\n contentType?: string\n ): Promise<T> {\n // Headers are already cloned and auth is already applied\n const requestHeaders = baseHeaders;\n\n const fetchInit: Omit<RequestInit, 'body'> & {\n path: string;\n method: string;\n\n query?: QueryParams | undefined;\n headers: Headers;\n body: RequestInit['body'] | undefined;\n } = {\n ...init,\n headers: requestHeaders,\n body: serializeBody(init.body, contentType),\n };\n\n // Set credentials from config if provided\n if (this.cfg.credentials !== undefined) {\n fetchInit.credentials = this.cfg.credentials;\n }\n\n // Execute beforeRequest hook\n if (this.hookRegistry.has('beforeRequest')) {\n await this.hookRegistry.execute('beforeRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n });\n }\n\n let controller: AbortController | undefined;\n let timeoutId: NodeJS.Timeout | undefined;\n const existingSignal = fetchInit.signal;\n\n // Setup timeout\n if (this.cfg.timeoutMs && typeof AbortController !== 'undefined') {\n controller = new AbortController();\n if (existingSignal) {\n if (existingSignal.aborted) {\n controller.abort();\n } else {\n existingSignal.addEventListener('abort', () => {\n controller?.abort();\n });\n }\n }\n fetchInit.signal = controller.signal;\n timeoutId = setTimeout(() => {\n controller?.abort();\n // Execute onTimeout hook\n if (this.hookRegistry.has('onTimeout')) {\n this.hookRegistry.execute('onTimeout', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n timeoutMs: this.cfg.timeoutMs,\n });\n }\n }, this.cfg.timeoutMs);\n }\n\n try {\n const fetchFn = this.cfg.fetch || fetch;\n const res = await fetchFn(url.toString(), fetchInit as RequestInit);\n\n // Execute afterRequest hook\n if (this.hookRegistry.has('afterRequest')) {\n await this.hookRegistry.execute('afterRequest', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n });\n }\n\n const parsed = await parseResponse(res);\n\n // Execute afterResponse hook\n if (this.hookRegistry.has('afterResponse')) {\n await this.hookRegistry.execute('afterResponse', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n response: res,\n data: parsed,\n });\n }\n\n if (!isSuccessResponse(res)) {\n const message = (parsed as { message?: string })?.message as\n | string\n | undefined;\n const error = createFetchError(\n res.status,\n message || `HTTP ${res.status}`,\n parsed,\n res.headers\n );\n\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error,\n });\n }\n\n throw error;\n }\n\n return parsed as T;\n } catch (err) {\n // Execute onError hook\n if (this.hookRegistry.has('onError')) {\n await this.hookRegistry.execute('onError', {\n url: url.toString(),\n init: fetchInit,\n attempt,\n error: err,\n });\n }\n\n // Re-throw with proper error type if needed\n if (err instanceof DOMException) {\n throw err;\n }\n if (err instanceof FetchError) {\n throw err;\n }\n\n // For network errors, try to extract status if available\n const status = (err as unknown as { status?: number })?.status as\n | number\n | undefined;\n const statusCode = typeof status === 'number' ? status : 0;\n if (typeof err === 'string') {\n throw createFetchError(statusCode, err);\n }\n throw createFetchError(\n statusCode,\n (err as Error)?.message || 'Network error'\n );\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Apply authentication strategies\n */\n private async applyAuthentication(headers: Headers, url: URL): Promise<void> {\n if (!this.cfg.authStrategies) {\n return;\n }\n\n for (const strategy of this.cfg.authStrategies) {\n await this.applyAuthStrategy(strategy, headers, url);\n }\n }\n\n /**\n * Apply a single authentication strategy\n */\n private async applyAuthStrategy(\n strategy: AuthStrategy,\n headers: Headers,\n url: URL\n ): Promise<void> {\n switch (strategy.type) {\n case 'bearer': {\n const token =\n typeof strategy.token === 'function'\n ? await strategy.token()\n : strategy.token;\n if (token != null) {\n const headerName = strategy.headerName || 'Authorization';\n headers.set(headerName, `Bearer ${String(token)}`);\n }\n break;\n }\n\n case 'basic': {\n const encoded = encodeBase64(\n `${strategy.username}:${strategy.password}`\n );\n headers.set('Authorization', `Basic ${encoded}`);\n break;\n }\n\n case 'apiKey': {\n const key =\n typeof strategy.key === 'function'\n ? await strategy.key()\n : strategy.key;\n if (key != null) {\n switch (strategy.location) {\n case 'header':\n headers.set(strategy.name, String(key));\n break;\n case 'query':\n url.searchParams.set(strategy.name, String(key));\n break;\n case 'cookie':\n headers.set('Cookie', `${strategy.name}=${String(key)}`);\n break;\n }\n }\n break;\n }\n\n case 'custom':\n await strategy.apply(headers, url);\n break;\n }\n }\n\n /**\n * Determine if an error should be retried\n */\n private shouldRetry(\n error: unknown,\n attempt: number,\n maxRetries: number,\n retryOn: number[]\n ): boolean {\n if (attempt >= maxRetries) {\n return false;\n }\n\n // Check custom retry condition\n if (this.cfg.retry?.retryOnError) {\n return this.cfg.retry.retryOnError(error);\n }\n\n // Check if it's a FetchError with a retryable status code\n if (error instanceof FetchError) {\n return retryOn.includes(error.status);\n }\n\n // Network errors (no status code) should be retried\n return true;\n }\n}\n","import type { AuthStrategy } from '@blimu/fetch';\nimport type { ClientOption } from './client';\n\nexport function buildAuthStrategies(cfg: ClientOption): AuthStrategy[] {\n const authStrategies: AuthStrategy[] = [...(cfg?.authStrategies ?? [])];\n\n if (cfg.bearer) {\n authStrategies.push({\n type: 'bearer',\n token: cfg.bearer,\n });\n }\n return authStrategies;\n}\n","import { parseSSEStream, parseNDJSONStream } from '@blimu/fetch';\n\nexport type PaginableQuery = { limit?: number; offset?: number } & Record<string, unknown>;\n\nexport async function* paginate<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n initialQuery: PaginableQuery = {},\n pageSize = 100\n): AsyncGenerator<T, void, unknown> {\n let offset = Number(initialQuery.offset ?? 0);\n const limit = Number(initialQuery.limit ?? pageSize);\n // shallow copy to avoid mutating caller\n const baseQuery: PaginableQuery = { ...initialQuery };\n while (true) {\n const page = await fetchPage({ ...baseQuery, limit, offset });\n const items = page.data ?? [];\n for (const item of items) {\n yield item;\n }\n if (!page.hasMore || items.length < limit) break;\n offset += limit;\n }\n}\n\nexport async function listAll<T>(\n fetchPage: (\n query?: PaginableQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ) => Promise<{ data?: T[]; hasMore?: boolean; limit?: number; offset?: number }>,\n query: PaginableQuery = {},\n pageSize = 100\n): Promise<T[]> {\n const out: T[] = [];\n for await (const item of paginate<T>(fetchPage, query, pageSize)) out.push(item);\n return out;\n}\n\n/**\n * Filters out undefined values from an array while preserving type safety\n * Useful for query keys where optional parameters might be undefined\n * Preserves tuple types when no undefined values are present\n */\nexport function isNotUndefined<T extends readonly unknown[]>(arr: T): T {\n // Type assertion: when no undefined values exist, tuple is preserved\n // When undefined values exist, they are filtered but type system can't infer exact tuple shape\n return arr.filter(\n (item): item is Exclude<T[number], undefined> => item !== undefined\n ) as unknown as T;\n}\n\n// Re-export streaming parsers from @blimu/fetch\nexport { parseSSEStream, parseNDJSONStream };\n","import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\nimport { isNotUndefined } from '../utils';\n\nexport class AuthService {\n constructor(private core: FetchClient) {}\n\n /**\n * POST /v1/auth/logout*\n * @summary Logout and invalidate session*/\n logout(init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/logout`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for logout\n * @returns ['v1/auth/logout']\n */\n logout__queryKeys(): readonly ['v1/auth/logout'] {\n return ['v1/auth/logout'] as const;\n }\n\n /**\n * POST /v1/auth/refresh*\n * @summary Refresh session token*/\n refresh(\n query?: Schema.AuthRefreshQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.RefreshResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/auth/refresh`,\n query,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for refresh\n * @returns ['v1/auth/refresh', query]\n */\n refresh__queryKeys(query?: Schema.AuthRefreshQuery): readonly string[] {\n const keys = ['v1/auth/refresh', query] as const;\n return isNotUndefined(keys) as readonly string[];\n }\n\n /**\n * GET /v1/auth/session*\n * @summary Get current session*/\n getSession(init?: Omit<RequestInit, 'method' | 'body'>): Promise<Schema.SessionResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/auth/session`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for getSession\n * @returns ['v1/auth/session']\n */\n getSession__queryKeys(): readonly ['v1/auth/session'] {\n return ['v1/auth/session'] as const;\n }\n}\n","import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\n\nexport class EntitlementsService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/client/entitlements/list-for-tenant/{tenantResourceId}*\n * @summary List entitlements for a tenant and all its sub-resources*\n * @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`).*/\n listForTenant(\n tenantResourceId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.EntitlementsListResult> {\n return this.core.request({\n method: 'GET',\n path: `/v1/client/entitlements/list-for-tenant/${encodeURIComponent(tenantResourceId)}`,\n ...(init ?? {}),\n });\n }\n /**\n * @summary Get query keys for listForTenant\n * @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]\n */\n listForTenant__queryKeys(\n tenantResourceId: string\n ): readonly ['v1/client/entitlements/list-for-tenant', string] {\n return ['v1/client/entitlements/list-for-tenant', tenantResourceId] as const;\n }\n}\n"],"mappings":"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","names":["FetchError","Error","message","status","data","headers","name","captureStackTrace","ClientError","ServerError","BadRequestError","UnauthorizedError","ForbiddenError","NotFoundError","MethodNotAllowedError","ConflictError","UnprocessableEntityError","TooManyRequestsError","InternalServerError","BadGatewayError","ServiceUnavailableError","GatewayTimeoutError","createFetchError","defaultMessage","HookRegistry","hooks","Map","config","registerFromConfig","stage","Object","entries","Array","isArray","hook","register","has","set","get","push","remove","index","indexOf","splice","clear","delete","execute","context","length","exponentialStrategy","attempt","baseBackoffMs","Math","pow","linearStrategy","getRetryStrategy","strategy","calculateRetryDelay","strategyFn","parseSSEStream","response","body","reader","getReader","decoder","TextDecoder","buffer","done","value","read","decode","stream","lines","split","pop","currentEvent","line","trim","undefined","colonIndex","field","substring","type","id","releaseLock","parseNDJSONStream","trimmed","parsed","JSON","parse","console","warn","parseChunkedStream","chunk","isBrowser","globalThis","window","document","isNode","process","versions","node","encodeBase64","str","btoa","Buffer","from","toString","isFetchAvailable","fetch","isAbortControllerAvailable","AbortController","getFetchErrorMessage","serializeQueryParams","query","params","URLSearchParams","key","item","append","String","buildUrl","baseUrl","path","normalizedPath","endsWith","slice","normalizedBaseUrl","baseUrlObj","URL","pathname","startsWith","url","keys","Set","searchParams","getAll","getContentType","FormData","serializeBody","contentType","Blob","ArrayBuffer","isView","stringify","parseResponse","includes","json","text","arrayBuffer","isSuccessResponse","ok","FetchClient","hookRegistry","cfg","baseURL","addAuthStrategy","authStrategies","clearAuthStrategies","useHook","removeHook","clearHooks","request","init","Headers","forEach","applyAuthentication","bodyContentType","retries","retry","baseBackoff","backoffMs","retryOn","retryStrategy","lastError","attemptUrl","attemptHeaders","doRequest","err","shouldRetry","serializedBody","error","retryCount","delay","Promise","resolve","setTimeout","success","requestStream","fetchInit","credentials","controller","timeoutId","existingSignal","signal","timeoutMs","aborted","abort","addEventListener","fetchFn","res","streamingFormat","transformedChunk","clearTimeout","baseHeaders","requestHeaders","DOMException","statusCode","applyAuthStrategy","token","headerName","encoded","username","password","location","apply","maxRetries","retryOnError"]}
|