@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.
Files changed (66) hide show
  1. package/README.md +21 -26
  2. package/dist/__tests__/example.test.cjs +17135 -0
  3. package/dist/__tests__/example.test.cjs.map +1 -0
  4. package/dist/__tests__/example.test.d.mts +2 -0
  5. package/dist/__tests__/example.test.d.ts +2 -0
  6. package/dist/__tests__/example.test.mjs +17134 -0
  7. package/dist/__tests__/example.test.mjs.map +1 -0
  8. package/dist/auth-strategies.cjs +40 -0
  9. package/dist/auth-strategies.cjs.map +1 -0
  10. package/dist/auth-strategies.d.mts +9 -0
  11. package/dist/auth-strategies.d.ts +9 -0
  12. package/dist/auth-strategies.mjs +15 -0
  13. package/dist/auth-strategies.mjs.map +1 -0
  14. package/dist/{client.js → client.cjs} +159 -66
  15. package/dist/client.cjs.map +1 -0
  16. package/dist/client.d.mts +12 -18
  17. package/dist/client.d.ts +12 -18
  18. package/dist/client.mjs +155 -64
  19. package/dist/client.mjs.map +1 -1
  20. package/dist/{index.js → index.cjs} +115 -132
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.mts +6 -19
  23. package/dist/index.d.ts +6 -19
  24. package/dist/index.mjs +112 -130
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/{schema-B4iFbKly.d.mts → schema-Z0doltxY.d.mts} +8 -10
  27. package/dist/{schema-B4iFbKly.d.ts → schema-Z0doltxY.d.ts} +8 -10
  28. package/dist/{schema.js → schema.cjs} +2 -1
  29. package/dist/schema.cjs.map +1 -0
  30. package/dist/schema.d.mts +1 -2
  31. package/dist/schema.d.ts +1 -2
  32. package/dist/{schema.zod-CyY7RTSY.d.mts → schema.zod-BaQz36Pd.d.mts} +2 -6
  33. package/dist/{schema.zod-CyY7RTSY.d.ts → schema.zod-BaQz36Pd.d.ts} +2 -6
  34. package/dist/{schema.zod.js → schema.zod.cjs} +16 -25
  35. package/dist/schema.zod.cjs.map +1 -0
  36. package/dist/schema.zod.d.mts +1 -1
  37. package/dist/schema.zod.d.ts +1 -1
  38. package/dist/schema.zod.mjs +14 -22
  39. package/dist/schema.zod.mjs.map +1 -1
  40. package/dist/services/{auth.js → auth.cjs} +16 -5
  41. package/dist/services/auth.cjs.map +1 -0
  42. package/dist/services/auth.d.mts +6 -8
  43. package/dist/services/auth.d.ts +6 -8
  44. package/dist/services/auth.mjs +12 -4
  45. package/dist/services/auth.mjs.map +1 -1
  46. package/dist/services/{entitlements.js → entitlements.cjs} +4 -6
  47. package/dist/services/entitlements.cjs.map +1 -0
  48. package/dist/services/entitlements.d.mts +4 -6
  49. package/dist/services/entitlements.d.ts +4 -6
  50. package/dist/services/entitlements.mjs +2 -5
  51. package/dist/services/entitlements.mjs.map +1 -1
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/dist/{utils.js → utils.cjs} +45 -26
  54. package/dist/utils.cjs.map +1 -0
  55. package/dist/utils.d.mts +4 -3
  56. package/dist/utils.d.ts +4 -3
  57. package/dist/utils.mjs +42 -25
  58. package/dist/utils.mjs.map +1 -1
  59. package/package.json +32 -13
  60. package/dist/client.js.map +0 -1
  61. package/dist/index.js.map +0 -1
  62. package/dist/schema.js.map +0 -1
  63. package/dist/schema.zod.js.map +0 -1
  64. package/dist/services/auth.js.map +0 -1
  65. package/dist/services/entitlements.js.map +0 -1
  66. package/dist/utils.js.map +0 -1
package/dist/index.mjs CHANGED
@@ -242,7 +242,7 @@ var HookRegistry = class {
242
242
  if (!this.hooks.has(stage)) {
243
243
  this.hooks.set(stage, []);
244
244
  }
245
- this.hooks.get(stage).push(hook);
245
+ this.hooks.get(stage)?.push(hook);
246
246
  }
247
247
  /**
248
248
  * Remove a specific hook from a stage
@@ -288,7 +288,14 @@ var HookRegistry = class {
288
288
  * Check if any hooks are registered for a stage
289
289
  */
290
290
  has(stage) {
291
- return this.hooks.has(stage) && this.hooks.get(stage).length > 0;
291
+ if (!this.hooks.has(stage)) {
292
+ return false;
293
+ }
294
+ const hooks = this.hooks.get(stage);
295
+ if (!hooks) {
296
+ return false;
297
+ }
298
+ return hooks.length > 0;
292
299
  }
293
300
  };
294
301
  var exponentialStrategy = /* @__PURE__ */ __name((attempt, baseBackoffMs) => {
@@ -403,7 +410,7 @@ async function* parseNDJSONStream(response) {
403
410
  try {
404
411
  const parsed = JSON.parse(trimmed);
405
412
  yield parsed;
406
- } catch (error) {
413
+ } catch {
407
414
  console.warn("Skipping invalid JSON line:", trimmed);
408
415
  }
409
416
  }
@@ -412,7 +419,7 @@ async function* parseNDJSONStream(response) {
412
419
  try {
413
420
  const parsed = JSON.parse(buffer.trim());
414
421
  yield parsed;
415
- } catch (error) {
422
+ } catch {
416
423
  console.warn("Skipping invalid JSON in buffer:", buffer.trim());
417
424
  }
418
425
  }
@@ -617,19 +624,17 @@ var FetchClient = class {
617
624
  * Add an authentication strategy
618
625
  */
619
626
  addAuthStrategy(strategy) {
620
- if (!this.cfg.auth) {
621
- this.cfg.auth = {
622
- strategies: []
623
- };
627
+ if (!this.cfg.authStrategies) {
628
+ this.cfg.authStrategies = [];
624
629
  }
625
- this.cfg.auth.strategies.push(strategy);
630
+ this.cfg.authStrategies.push(strategy);
626
631
  }
627
632
  /**
628
633
  * Remove all authentication strategies
629
634
  */
630
635
  clearAuthStrategies() {
631
- if (this.cfg.auth) {
632
- this.cfg.auth.strategies = [];
636
+ if (this.cfg.authStrategies) {
637
+ this.cfg.authStrategies = [];
633
638
  }
634
639
  }
635
640
  /**
@@ -653,8 +658,9 @@ var FetchClient = class {
653
658
  /**
654
659
  * Make an HTTP request
655
660
  */
661
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
656
662
  async request(init) {
657
- let url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
663
+ const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
658
664
  const headers = new Headers(this.cfg.headers || {});
659
665
  if (init.headers) {
660
666
  if (init.headers instanceof Headers) {
@@ -691,7 +697,7 @@ var FetchClient = class {
691
697
  let lastError;
692
698
  for (let attempt = 0; attempt <= retries + 1; attempt++) {
693
699
  try {
694
- let attemptUrl = buildUrl(this.cfg.baseURL || "", init.path, init.query);
700
+ const attemptUrl = buildUrl(this.cfg.baseURL || "", init.path, init.query);
695
701
  const attemptHeaders = new Headers(headers);
696
702
  await this.applyAuthentication(attemptHeaders, attemptUrl);
697
703
  return await this.doRequest(attemptUrl, init, attemptHeaders, attempt, bodyContentType);
@@ -700,11 +706,13 @@ var FetchClient = class {
700
706
  const shouldRetry = this.shouldRetry(err, attempt, retries, retryOn);
701
707
  if (shouldRetry) {
702
708
  if (this.hookRegistry.has("beforeRetry")) {
709
+ const serializedBody = serializeBody(init.body, bodyContentType);
703
710
  await this.hookRegistry.execute("beforeRetry", {
704
711
  url: url.toString(),
705
712
  init: {
706
713
  ...init,
707
- headers
714
+ headers,
715
+ body: serializedBody
708
716
  },
709
717
  attempt,
710
718
  error: err,
@@ -714,11 +722,13 @@ var FetchClient = class {
714
722
  const delay = calculateRetryDelay(attempt, retryStrategy, baseBackoff);
715
723
  await new Promise((resolve) => setTimeout(resolve, delay));
716
724
  if (this.hookRegistry.has("afterRetry")) {
725
+ const serializedBody = serializeBody(init.body, bodyContentType);
717
726
  await this.hookRegistry.execute("afterRetry", {
718
727
  url: url.toString(),
719
728
  init: {
720
729
  ...init,
721
- headers
730
+ headers,
731
+ body: serializedBody
722
732
  },
723
733
  attempt,
724
734
  error: err,
@@ -737,7 +747,7 @@ var FetchClient = class {
737
747
  * Make a streaming HTTP request
738
748
  */
739
749
  async *requestStream(init) {
740
- let url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
750
+ const url = buildUrl(this.cfg.baseURL || "", init.path, init.query);
741
751
  const headers = new Headers(this.cfg.headers || {});
742
752
  if (init.headers) {
743
753
  if (init.headers instanceof Headers) {
@@ -811,7 +821,8 @@ var FetchClient = class {
811
821
  }
812
822
  if (!res.ok) {
813
823
  const parsed = await parseResponse(res);
814
- const error = createFetchError(res.status, parsed?.message || `HTTP ${res.status}`, parsed, res.headers);
824
+ const message = parsed?.message;
825
+ const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
815
826
  if (this.hookRegistry.has("onError")) {
816
827
  await this.hookRegistry.execute("onError", {
817
828
  url: url.toString(),
@@ -833,7 +844,7 @@ var FetchClient = class {
833
844
  const streamingFormat = init.streamingFormat || "chunked";
834
845
  if (streamingFormat === "sse") {
835
846
  for await (const chunk of parseSSEStream(res)) {
836
- let transformedChunk = chunk;
847
+ const transformedChunk = chunk;
837
848
  if (this.hookRegistry.has("onStreamChunk")) {
838
849
  await this.hookRegistry.execute("onStreamChunk", {
839
850
  url: url.toString(),
@@ -846,7 +857,7 @@ var FetchClient = class {
846
857
  }
847
858
  } else if (streamingFormat === "ndjson") {
848
859
  for await (const chunk of parseNDJSONStream(res)) {
849
- let transformedChunk = chunk;
860
+ const transformedChunk = chunk;
850
861
  if (this.hookRegistry.has("onStreamChunk")) {
851
862
  await this.hookRegistry.execute("onStreamChunk", {
852
863
  url: url.toString(),
@@ -859,7 +870,7 @@ var FetchClient = class {
859
870
  }
860
871
  } else {
861
872
  for await (const chunk of parseChunkedStream(res)) {
862
- let transformedChunk = chunk;
873
+ const transformedChunk = chunk;
863
874
  if (this.hookRegistry.has("onStreamChunk")) {
864
875
  await this.hookRegistry.execute("onStreamChunk", {
865
876
  url: url.toString(),
@@ -964,7 +975,8 @@ var FetchClient = class {
964
975
  });
965
976
  }
966
977
  if (!isSuccessResponse(res)) {
967
- const error = createFetchError(res.status, parsed?.message || `HTTP ${res.status}`, parsed, res.headers);
978
+ const message = parsed?.message;
979
+ const error = createFetchError(res.status, message || `HTTP ${res.status}`, parsed, res.headers);
968
980
  if (this.hookRegistry.has("onError")) {
969
981
  await this.hookRegistry.execute("onError", {
970
982
  url: url.toString(),
@@ -1007,10 +1019,10 @@ var FetchClient = class {
1007
1019
  * Apply authentication strategies
1008
1020
  */
1009
1021
  async applyAuthentication(headers, url) {
1010
- if (!this.cfg.auth?.strategies) {
1022
+ if (!this.cfg.authStrategies) {
1011
1023
  return;
1012
1024
  }
1013
- for (const strategy of this.cfg.auth.strategies) {
1025
+ for (const strategy of this.cfg.authStrategies) {
1014
1026
  await this.applyAuthStrategy(strategy, headers, url);
1015
1027
  }
1016
1028
  }
@@ -1071,50 +1083,46 @@ var FetchClient = class {
1071
1083
  }
1072
1084
  };
1073
1085
 
1074
- // src/client.ts
1075
- var CoreClient = class extends FetchClient {
1076
- constructor(cfg = {}) {
1077
- const authStrategies = [];
1078
- const { auth: _existingAuth, bearer, ...restCfg } = cfg;
1079
- if (cfg.bearer) {
1080
- const bearerValue = cfg.bearer;
1081
- if (typeof bearerValue === "string") {
1082
- authStrategies.push({
1083
- type: "bearer",
1084
- token: () => bearerValue
1085
- });
1086
- } else if (typeof bearerValue === "function") {
1087
- authStrategies.push({
1088
- type: "bearer",
1089
- token: bearerValue
1090
- });
1091
- }
1092
- }
1093
- const finalAuthStrategies = [
1094
- ..._existingAuth?.strategies || [],
1095
- ...authStrategies
1096
- ];
1097
- const fetchConfig = {
1098
- ...restCfg,
1099
- baseURL: cfg.baseURL ?? "https://api.blimu.dev",
1100
- // Explicitly set auth after restCfg to ensure it's not overwritten
1101
- // (restCfg might have an auth property that we want to replace)
1102
- ...finalAuthStrategies.length > 0 ? {
1103
- auth: {
1104
- strategies: finalAuthStrategies
1105
- }
1106
- } : {}
1107
- // Hooks are passed through directly from FetchClientConfig (no mapping needed)
1108
- };
1109
- super(fetchConfig);
1110
- }
1111
- async request(init) {
1112
- return await super.request(init);
1086
+ // src/auth-strategies.ts
1087
+ function buildAuthStrategies(cfg) {
1088
+ const authStrategies = [...cfg?.authStrategies ?? []];
1089
+ if (cfg.bearer) {
1090
+ authStrategies.push({
1091
+ type: "bearer",
1092
+ token: cfg.bearer
1093
+ });
1113
1094
  }
1114
- async *requestStream(init) {
1115
- yield* super.requestStream(init);
1095
+ return authStrategies;
1096
+ }
1097
+
1098
+ // src/schema.ts
1099
+ var schema_exports = {};
1100
+
1101
+ // src/utils.ts
1102
+ async function* paginate(fetchPage, initialQuery = {}, pageSize = 100) {
1103
+ let offset = Number(initialQuery.offset ?? 0);
1104
+ const limit = Number(initialQuery.limit ?? pageSize);
1105
+ const baseQuery = { ...initialQuery };
1106
+ while (true) {
1107
+ const page = await fetchPage({ ...baseQuery, limit, offset });
1108
+ const items = page.data ?? [];
1109
+ for (const item of items) {
1110
+ yield item;
1111
+ }
1112
+ if (!page.hasMore || items.length < limit) break;
1113
+ offset += limit;
1116
1114
  }
1117
- };
1115
+ }
1116
+ async function listAll(fetchPage, query = {}, pageSize = 100) {
1117
+ const out = [];
1118
+ for await (const item of paginate(fetchPage, query, pageSize)) out.push(item);
1119
+ return out;
1120
+ }
1121
+ function isNotUndefined(arr) {
1122
+ return arr.filter(
1123
+ (item) => item !== void 0
1124
+ );
1125
+ }
1118
1126
 
1119
1127
  // src/services/auth.ts
1120
1128
  var AuthService = class {
@@ -1128,7 +1136,7 @@ var AuthService = class {
1128
1136
  return this.core.request({
1129
1137
  method: "POST",
1130
1138
  path: `/v1/auth/logout`,
1131
- ...init || {}
1139
+ ...init ?? {}
1132
1140
  });
1133
1141
  }
1134
1142
  /**
@@ -1146,7 +1154,7 @@ var AuthService = class {
1146
1154
  method: "POST",
1147
1155
  path: `/v1/auth/refresh`,
1148
1156
  query,
1149
- ...init || {}
1157
+ ...init ?? {}
1150
1158
  });
1151
1159
  }
1152
1160
  /**
@@ -1154,7 +1162,8 @@ var AuthService = class {
1154
1162
  * @returns ['v1/auth/refresh', query]
1155
1163
  */
1156
1164
  refresh__queryKeys(query) {
1157
- return ["v1/auth/refresh", query];
1165
+ const keys = ["v1/auth/refresh", query];
1166
+ return isNotUndefined(keys);
1158
1167
  }
1159
1168
  /**
1160
1169
  * GET /v1/auth/session*
@@ -1163,7 +1172,7 @@ var AuthService = class {
1163
1172
  return this.core.request({
1164
1173
  method: "GET",
1165
1174
  path: `/v1/auth/session`,
1166
- ...init || {}
1175
+ ...init ?? {}
1167
1176
  });
1168
1177
  }
1169
1178
  /**
@@ -1188,7 +1197,7 @@ var EntitlementsService = class {
1188
1197
  return this.core.request({
1189
1198
  method: "GET",
1190
1199
  path: `/v1/client/entitlements/list-for-tenant/${encodeURIComponent(tenantResourceId)}`,
1191
- ...init || {}
1200
+ ...init ?? {}
1192
1201
  });
1193
1202
  }
1194
1203
  /**
@@ -1196,70 +1205,53 @@ var EntitlementsService = class {
1196
1205
  * @returns ['v1/client/entitlements/list-for-tenant', tenantResourceId]
1197
1206
  */
1198
1207
  listForTenant__queryKeys(tenantResourceId) {
1199
- return [
1200
- "v1/client/entitlements/list-for-tenant",
1201
- tenantResourceId
1202
- ];
1208
+ return ["v1/client/entitlements/list-for-tenant", tenantResourceId];
1203
1209
  }
1204
1210
  };
1205
1211
 
1206
- // src/utils.ts
1207
- async function* paginate(fetchPage, initialQuery = {}, pageSize = 100) {
1208
- let offset = Number(initialQuery.offset ?? 0);
1209
- const limit = Number(initialQuery.limit ?? pageSize);
1210
- const baseQuery = { ...initialQuery };
1211
- while (true) {
1212
- const page = await fetchPage({ ...baseQuery, limit, offset });
1213
- const items = page.data ?? [];
1214
- for (const item of items) {
1215
- yield item;
1216
- }
1217
- if (!page.hasMore || items.length < limit) break;
1218
- offset += limit;
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);
1219
1227
  }
1220
- }
1221
- async function listAll(fetchPage, query = {}, pageSize = 100) {
1222
- const out = [];
1223
- for await (const item of paginate(fetchPage, query, pageSize))
1224
- out.push(item);
1225
- return out;
1226
- }
1227
-
1228
- // src/schema.ts
1229
- var schema_exports = {};
1228
+ };
1229
+ var BlimuError = FetchError;
1230
1230
 
1231
1231
  // src/schema.zod.ts
1232
1232
  var schema_zod_exports = {};
1233
1233
  __export(schema_zod_exports, {
1234
1234
  AuthRefreshQuerySchema: () => AuthRefreshQuerySchema,
1235
- EntitlementTypeSchema: () => EntitlementTypeSchema,
1236
1235
  EntitlementsListResultSchema: () => EntitlementsListResultSchema,
1237
1236
  RefreshResponseSchema: () => RefreshResponseSchema,
1238
- ResourceTypeSchema: () => ResourceTypeSchema,
1239
1237
  SessionResponseSchema: () => SessionResponseSchema
1240
1238
  });
1241
1239
  import { z } from "zod";
1242
- var EntitlementTypeSchema = z.string();
1243
- var ResourceTypeSchema = z.string();
1244
1240
  var EntitlementsListResultSchema = z.object({
1245
- results: z.array(
1246
- z.object({
1247
- entitlements: z.array(
1248
- z.object({
1249
- allowed: z.boolean(),
1250
- allowedByPlan: z.boolean(),
1251
- allowedByRole: z.boolean(),
1252
- allowedPlans: z.array(z.string()).optional(),
1253
- allowedRoles: z.array(z.string()),
1254
- currentPlan: z.string().optional(),
1255
- currentRole: z.string().optional(),
1256
- entitlement: EntitlementTypeSchema
1257
- })
1258
- ),
1259
- resourceId: z.string(),
1260
- resourceType: ResourceTypeSchema
1261
- })
1262
- )
1241
+ results: z.object({
1242
+ entitlements: z.object({
1243
+ allowed: z.boolean(),
1244
+ allowedByPlan: z.boolean(),
1245
+ allowedByRole: z.boolean(),
1246
+ allowedPlans: z.string().array().optional(),
1247
+ allowedRoles: z.string().array(),
1248
+ currentPlan: z.string().optional(),
1249
+ currentRole: z.string().optional(),
1250
+ entitlement: z.string()
1251
+ }).array(),
1252
+ resourceId: z.string(),
1253
+ resourceType: z.string()
1254
+ }).array()
1263
1255
  });
1264
1256
  var RefreshResponseSchema = z.object({ sessionToken: z.string() });
1265
1257
  var SessionResponseSchema = z.object({
@@ -1275,16 +1267,6 @@ var SessionResponseSchema = z.object({
1275
1267
  var AuthRefreshQuerySchema = z.object({
1276
1268
  __lh_jwt: z.string().optional()
1277
1269
  });
1278
-
1279
- // src/index.ts
1280
- var Blimu = class {
1281
- constructor(options) {
1282
- const core = new CoreClient(options);
1283
- this.auth = new AuthService(core);
1284
- this.entitlements = new EntitlementsService(core);
1285
- }
1286
- };
1287
- var BlimuError = FetchError;
1288
1270
  export {
1289
1271
  AuthService,
1290
1272
  BadGatewayError,
@@ -1293,7 +1275,6 @@ export {
1293
1275
  BlimuError,
1294
1276
  ClientError,
1295
1277
  ConflictError,
1296
- CoreClient,
1297
1278
  EntitlementsService,
1298
1279
  FetchClient,
1299
1280
  FetchError,
@@ -1322,6 +1303,7 @@ export {
1322
1303
  isBrowser,
1323
1304
  isFetchAvailable,
1324
1305
  isNode,
1306
+ isNotUndefined,
1325
1307
  isSuccessResponse,
1326
1308
  linearStrategy,
1327
1309
  listAll,