@blimu/backend 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 (145) hide show
  1. package/README.md +6 -13
  2. package/dist/__tests__/token-verifier.test.cjs +17662 -0
  3. package/dist/__tests__/token-verifier.test.cjs.map +1 -0
  4. package/dist/__tests__/token-verifier.test.d.mts +2 -0
  5. package/dist/__tests__/token-verifier.test.d.ts +2 -0
  6. package/dist/__tests__/token-verifier.test.mjs +17661 -0
  7. package/dist/__tests__/token-verifier.test.mjs.map +1 -0
  8. package/dist/auth-strategies.cjs +42 -0
  9. package/dist/auth-strategies.cjs.map +1 -0
  10. package/dist/auth-strategies.d.mts +16 -0
  11. package/dist/auth-strategies.d.ts +16 -0
  12. package/dist/auth-strategies.mjs +17 -0
  13. package/dist/auth-strategies.mjs.map +1 -0
  14. package/dist/client.cjs +483 -0
  15. package/dist/client.cjs.map +1 -0
  16. package/dist/client.d.mts +26 -18
  17. package/dist/client.d.ts +26 -18
  18. package/dist/client.mjs +447 -39
  19. package/dist/client.mjs.map +1 -1
  20. package/dist/{main.js → index.cjs} +294 -399
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.mts +15 -33
  23. package/dist/index.d.ts +15 -33
  24. package/dist/index.mjs +440 -330
  25. package/dist/index.mjs.map +1 -1
  26. package/dist/{schema-B1usIXCr.d.mts → schema-BbKn_i-U.d.mts} +82 -93
  27. package/dist/{schema-B1usIXCr.d.ts → schema-BbKn_i-U.d.ts} +82 -93
  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-CRNAHxbc.d.mts → schema.zod-DtXVS-1g.d.mts} +38 -48
  33. package/dist/{schema.zod-CRNAHxbc.d.ts → schema.zod-DtXVS-1g.d.ts} +38 -48
  34. package/dist/{schema.zod.js → schema.zod.cjs} +175 -248
  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 +173 -242
  39. package/dist/schema.zod.mjs.map +1 -1
  40. package/dist/services/{bulk_resources.js → bulk_resources.cjs} +4 -2
  41. package/dist/services/bulk_resources.cjs.map +1 -0
  42. package/dist/services/bulk_resources.d.mts +4 -6
  43. package/dist/services/bulk_resources.d.ts +4 -6
  44. package/dist/services/bulk_resources.mjs +2 -1
  45. package/dist/services/bulk_resources.mjs.map +1 -1
  46. package/dist/services/{bulk_roles.js → bulk_roles.cjs} +4 -2
  47. package/dist/services/bulk_roles.cjs.map +1 -0
  48. package/dist/services/bulk_roles.d.mts +3 -5
  49. package/dist/services/bulk_roles.d.ts +3 -5
  50. package/dist/services/bulk_roles.mjs +2 -1
  51. package/dist/services/bulk_roles.mjs.map +1 -1
  52. package/dist/services/{entitlements.js → entitlements.cjs} +6 -4
  53. package/dist/services/entitlements.cjs.map +1 -0
  54. package/dist/services/entitlements.d.mts +4 -6
  55. package/dist/services/entitlements.d.ts +4 -6
  56. package/dist/services/entitlements.mjs +4 -3
  57. package/dist/services/entitlements.mjs.map +1 -1
  58. package/dist/services/{plans.js → plans.cjs} +6 -4
  59. package/dist/services/plans.cjs.map +1 -0
  60. package/dist/services/plans.d.mts +6 -8
  61. package/dist/services/plans.d.ts +6 -8
  62. package/dist/services/plans.mjs +4 -3
  63. package/dist/services/plans.mjs.map +1 -1
  64. package/dist/services/{resource_members.js → resource_members.cjs} +4 -2
  65. package/dist/services/resource_members.cjs.map +1 -0
  66. package/dist/services/resource_members.d.mts +4 -6
  67. package/dist/services/resource_members.d.ts +4 -6
  68. package/dist/services/resource_members.mjs +2 -1
  69. package/dist/services/resource_members.mjs.map +1 -1
  70. package/dist/services/{resources.js → resources.cjs} +8 -6
  71. package/dist/services/resources.cjs.map +1 -0
  72. package/dist/services/resources.d.mts +8 -10
  73. package/dist/services/resources.d.ts +8 -10
  74. package/dist/services/resources.mjs +6 -5
  75. package/dist/services/resources.mjs.map +1 -1
  76. package/dist/services/{roles.js → roles.cjs} +6 -4
  77. package/dist/services/roles.cjs.map +1 -0
  78. package/dist/services/roles.d.mts +4 -6
  79. package/dist/services/roles.d.ts +4 -6
  80. package/dist/services/roles.mjs +4 -3
  81. package/dist/services/roles.mjs.map +1 -1
  82. package/dist/services/{usage.js → usage.cjs} +8 -6
  83. package/dist/services/usage.cjs.map +1 -0
  84. package/dist/services/usage.d.mts +5 -7
  85. package/dist/services/usage.d.ts +5 -7
  86. package/dist/services/usage.mjs +6 -5
  87. package/dist/services/usage.mjs.map +1 -1
  88. package/dist/services/{users.js → users.cjs} +9 -7
  89. package/dist/services/users.cjs.map +1 -0
  90. package/dist/services/users.d.mts +3 -5
  91. package/dist/services/users.d.ts +3 -5
  92. package/dist/services/users.mjs +7 -6
  93. package/dist/services/users.mjs.map +1 -1
  94. package/dist/{token-verifier.js → token-verifier.cjs} +14 -31
  95. package/dist/token-verifier.cjs.map +1 -0
  96. package/dist/token-verifier.d.mts +5 -5
  97. package/dist/token-verifier.d.ts +5 -5
  98. package/dist/token-verifier.mjs +13 -34
  99. package/dist/token-verifier.mjs.map +1 -1
  100. package/dist/tsconfig.tsbuildinfo +1 -1
  101. package/dist/{utils.js → utils.cjs} +10 -3
  102. package/dist/utils.cjs.map +1 -0
  103. package/dist/utils.d.mts +4 -3
  104. package/dist/utils.d.ts +4 -3
  105. package/dist/utils.mjs +7 -2
  106. package/dist/utils.mjs.map +1 -1
  107. package/package.json +37 -25
  108. package/dist/client.js +0 -70
  109. package/dist/client.js.map +0 -1
  110. package/dist/index.js +0 -1042
  111. package/dist/index.js.map +0 -1
  112. package/dist/main.d.mts +0 -19
  113. package/dist/main.d.ts +0 -19
  114. package/dist/main.js.map +0 -1
  115. package/dist/main.mjs +0 -1264
  116. package/dist/main.mjs.map +0 -1
  117. package/dist/schema.js.map +0 -1
  118. package/dist/schema.zod.js.map +0 -1
  119. package/dist/services/bulk_resources.js.map +0 -1
  120. package/dist/services/bulk_roles.js.map +0 -1
  121. package/dist/services/entitlements.js.map +0 -1
  122. package/dist/services/plans.js.map +0 -1
  123. package/dist/services/resource_members.js.map +0 -1
  124. package/dist/services/resources.js.map +0 -1
  125. package/dist/services/roles.js.map +0 -1
  126. package/dist/services/usage.js.map +0 -1
  127. package/dist/services/users.js.map +0 -1
  128. package/dist/token-verifier.js.map +0 -1
  129. package/dist/utils.js.map +0 -1
  130. package/src/client.ts +0 -74
  131. package/src/index.ts +0 -55
  132. package/src/main.ts +0 -3
  133. package/src/schema.ts +0 -430
  134. package/src/schema.zod.ts +0 -558
  135. package/src/services/bulk_resources.ts +0 -24
  136. package/src/services/bulk_roles.ts +0 -22
  137. package/src/services/entitlements.ts +0 -58
  138. package/src/services/plans.ts +0 -57
  139. package/src/services/resource_members.ts +0 -25
  140. package/src/services/resources.ts +0 -91
  141. package/src/services/roles.ts +0 -58
  142. package/src/services/usage.ts +0 -93
  143. package/src/services/users.ts +0 -100
  144. package/src/token-verifier.ts +0 -280
  145. package/src/utils.ts +0 -56
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/usage.ts"],"sourcesContent":["import { CoreClient } from '../client';\nimport * as Schema from '../schema';\nimport type { ResourceType, UsageLimitType } from '@blimu/types';\n\nexport class UsageService {\n constructor(private core: CoreClient) {}\n\n /**\n * GET /v1/usage/balance/{resourceType}/{resourceId}/{limitType}*\n * @summary Get wallet balance*\n * @description Retrieves the current balance of a usage wallet for a specific resource and limit type within a given time period. The balance reflects all credits and consumption transactions.*/\n getBalance(\n resourceType: ResourceType,\n resourceId: string,\n limitType: UsageLimitType,\n query?: Schema.UsageGetBalanceQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.BalanceResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/usage/balance/${encodeURIComponent(resourceType)}/${encodeURIComponent(resourceId)}/${encodeURIComponent(limitType)}`,\n query,\n ...(init || {}),\n });\n }\n\n /**\n * POST /v1/usage/check*\n * @summary Check if consumption is allowed*\n * @description Checks whether a specific amount of consumption is allowed for a resource and limit type within a given time period. Returns the current balance, requested amount, and remaining balance after the consumption.*/\n checkLimit(\n body: Schema.UsageCheckBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.CheckLimitResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/check`,\n body: body as any,\n ...(init || {}),\n });\n }\n\n /**\n * POST /v1/usage/consume*\n * @summary Record consumption (inserts negative amount)*\n * @description Records consumption from a usage wallet for a specific resource and limit type. This decreases the available balance. Consumption can be tagged for tracking purposes.*/\n consume(\n body: Schema.UsageConsumeBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UsageWalletResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/consume`,\n body: body as any,\n ...(init || {}),\n });\n }\n\n /**\n * POST /v1/usage/credit*\n * @summary Add credits to wallet (inserts positive amount)*\n * @description Adds credits to a usage wallet for a specific resource and limit type. This increases the available balance for usage-based limits. Credits can be tagged for tracking purposes.*/\n credit(\n body: Schema.UsageCreditBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UsageWalletResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/credit`,\n body: body as any,\n ...(init || {}),\n });\n }\n\n /**\n * GET /v1/usage/transactions/{resourceType}/{resourceId}/{limitType}*\n * @summary Get transaction history*\n * @description Retrieves the transaction history for a usage wallet, including all credits and consumption records. Supports filtering by time period and date range.*/\n getTransactionHistory(\n resourceType: ResourceType,\n resourceId: string,\n limitType: UsageLimitType,\n query?: Schema.UsageGetTransactionHistoryQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.TransactionHistoryResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/usage/transactions/${encodeURIComponent(resourceType)}/${encodeURIComponent(resourceId)}/${encodeURIComponent(limitType)}`,\n query,\n ...(init || {}),\n });\n }\n}\n"],"mappings":";AAIO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvC,WACE,cACA,YACA,WACA,OACA,MACiC;AACjC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,qBAAqB,mBAAmB,YAAY,CAAC,IAAI,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,MAC9H;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WACE,MACA,MACoC;AACpC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QACE,MACA,MACqC;AACrC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,MACA,MACqC;AACrC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBACE,cACA,YACA,WACA,OACA,MAC4C;AAC5C,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,0BAA0B,mBAAmB,YAAY,CAAC,IAAI,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,MACnI;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/services/usage.ts"],"sourcesContent":["import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\n\nexport class UsageService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/usage/balance/{resourceType}/{resourceId}/{limitType}*\n * @summary Get wallet balance*\n * @description Retrieves the current balance of a usage wallet for a specific resource and limit type within a given time period. The balance reflects all credits and consumption transactions.*/\n getBalance(\n resourceType: string,\n resourceId: string,\n limitType: string,\n query?: Schema.UsageGetBalanceQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.BalanceResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/usage/balance/${encodeURIComponent(resourceType)}/${encodeURIComponent(resourceId)}/${encodeURIComponent(limitType)}`,\n query,\n ...(init ?? {}),\n });\n }\n\n /**\n * POST /v1/usage/check*\n * @summary Check if consumption is allowed*\n * @description Checks whether a specific amount of consumption is allowed for a resource and limit type within a given time period. Returns the current balance, requested amount, and remaining balance after the consumption.*/\n checkLimit(\n body: Schema.UsageCheckBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.CheckLimitResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/check`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * POST /v1/usage/consume*\n * @summary Record consumption (inserts negative amount)*\n * @description Records consumption from a usage wallet for a specific resource and limit type. This decreases the available balance. Consumption can be tagged for tracking purposes.*/\n consume(\n body: Schema.UsageConsumeBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UsageWalletResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/consume`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * POST /v1/usage/credit*\n * @summary Add credits to wallet (inserts positive amount)*\n * @description Adds credits to a usage wallet for a specific resource and limit type. This increases the available balance for usage-based limits. Credits can be tagged for tracking purposes.*/\n credit(\n body: Schema.UsageCreditBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UsageWalletResponse> {\n return this.core.request({\n method: 'POST',\n path: `/v1/usage/credit`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * GET /v1/usage/transactions/{resourceType}/{resourceId}/{limitType}*\n * @summary Get transaction history*\n * @description Retrieves the transaction history for a usage wallet, including all credits and consumption records. Supports filtering by time period and date range.*/\n getTransactionHistory(\n resourceType: string,\n resourceId: string,\n limitType: string,\n query?: Schema.UsageGetTransactionHistoryQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.TransactionHistoryResponse> {\n return this.core.request({\n method: 'GET',\n path: `/v1/usage/transactions/${encodeURIComponent(resourceType)}/${encodeURIComponent(resourceId)}/${encodeURIComponent(limitType)}`,\n query,\n ...(init ?? {}),\n });\n }\n}\n"],"mappings":";AAAA,OAA4B;AAGrB,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAmB;AAAnB;AAAA,EAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,WACE,cACA,YACA,WACA,OACA,MACiC;AACjC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,qBAAqB,mBAAmB,YAAY,CAAC,IAAI,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,MAC9H;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WACE,MACA,MACoC;AACpC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QACE,MACA,MACqC;AACrC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,MACA,MACqC;AACrC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,sBACE,cACA,YACA,WACA,OACA,MAC4C;AAC5C,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,0BAA0B,mBAAmB,YAAY,CAAC,IAAI,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,SAAS,CAAC;AAAA,MACnI;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AACF;","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;
@@ -22,6 +23,7 @@ __export(users_exports, {
22
23
  UsersService: () => UsersService
23
24
  });
24
25
  module.exports = __toCommonJS(users_exports);
26
+ var import_fetch = require("@blimu/fetch");
25
27
  var UsersService = class {
26
28
  constructor(core) {
27
29
  this.core = core;
@@ -35,7 +37,7 @@ var UsersService = class {
35
37
  method: "GET",
36
38
  path: `/v1/users`,
37
39
  query,
38
- ...init || {}
40
+ ...init ?? {}
39
41
  });
40
42
  }
41
43
  /**
@@ -47,7 +49,7 @@ var UsersService = class {
47
49
  method: "POST",
48
50
  path: `/v1/users`,
49
51
  body,
50
- ...init || {}
52
+ ...init ?? {}
51
53
  });
52
54
  }
53
55
  /**
@@ -58,7 +60,7 @@ var UsersService = class {
58
60
  return this.core.request({
59
61
  method: "DELETE",
60
62
  path: `/v1/users/${encodeURIComponent(userId)}`,
61
- ...init || {}
63
+ ...init ?? {}
62
64
  });
63
65
  }
64
66
  /**
@@ -69,7 +71,7 @@ var UsersService = class {
69
71
  return this.core.request({
70
72
  method: "GET",
71
73
  path: `/v1/users/${encodeURIComponent(userId)}`,
72
- ...init || {}
74
+ ...init ?? {}
73
75
  });
74
76
  }
75
77
  /**
@@ -81,7 +83,7 @@ var UsersService = class {
81
83
  method: "PUT",
82
84
  path: `/v1/users/${encodeURIComponent(userId)}`,
83
85
  body,
84
- ...init || {}
86
+ ...init ?? {}
85
87
  });
86
88
  }
87
89
  /**
@@ -92,7 +94,7 @@ var UsersService = class {
92
94
  return this.core.request({
93
95
  method: "GET",
94
96
  path: `/v1/users/${encodeURIComponent(userId)}/effective-user-resources-roles`,
95
- ...init || {}
97
+ ...init ?? {}
96
98
  });
97
99
  }
98
100
  };
@@ -100,4 +102,4 @@ var UsersService = class {
100
102
  0 && (module.exports = {
101
103
  UsersService
102
104
  });
103
- //# sourceMappingURL=users.js.map
105
+ //# sourceMappingURL=users.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/services/users.ts"],"sourcesContent":["import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\n\nexport class UsersService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/users*\n * @summary List users*\n * @description Retrieves a paginated list of users in your environment. Supports search functionality to filter users by email, name, or lookup key.*/\n list(\n query?: Schema.UsersListQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users`,\n query,\n ...(init ?? {}),\n });\n }\n\n /**\n * POST /v1/users*\n * @summary Create a user*\n * @description Creates a new user in your environment. The lookupKey is a unique identifier that you can use to reference the user in your system. It should be stable and not change over time.*/\n create(\n body: Schema.UserCreateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'POST',\n path: `/v1/users`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * DELETE /v1/users/{userId}*\n * @summary Delete a user*\n * @description Deletes a user by their ID or lookup key. This operation is permanent and cannot be undone. Deleting a user will also remove all role assignments for that user.*/\n delete(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown> {\n return this.core.request({\n method: 'DELETE',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init ?? {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}*\n * @summary Get a user by ID*\n * @description Retrieves a single user by their ID or lookup key. Returns user information including email, name, and metadata.*/\n read(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Schema.User> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init ?? {}),\n });\n }\n\n /**\n * PUT /v1/users/{userId}*\n * @summary Update a user*\n * @description Updates an existing user. You can modify email, name, and other user properties. The lookupKey can be updated but should remain stable.*/\n update(\n userId: string,\n body: Schema.UserUpdateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'PUT',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}/effective-user-resources-roles*\n * @summary List effective user resources roles*\n * @description Retrieves all resources and roles for a user, including inherited roles from parent resources. The response indicates whether each role is directly assigned or inherited through resource hierarchies.*/\n listEffectiveUserResourcesRoles(\n userId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserResourceList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}/effective-user-resources-roles`,\n ...(init ?? {}),\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA4B;AAGrB,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAmB;AAAnB;AAAA,EAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,KACE,OACA,MAC0B;AAC1B,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAAgB,MAA+D;AACpF,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,QAAgB,MAAmE;AACtF,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,QACA,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gCACE,QACA,MACkC;AAClC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -1,11 +1,9 @@
1
- import { CoreClient } from '../client.mjs';
2
- import { A as UsersListQuery, D as UserList, F as UserCreateBody, G as User, H as UserUpdateBody, I as UserResourceList } from '../schema-B1usIXCr.mjs';
3
- import '@blimu/fetch';
4
- import '@blimu/types';
1
+ import { FetchClient } from '@blimu/fetch';
2
+ import { A as UsersListQuery, D as UserList, F as UserCreateBody, G as User, H as UserUpdateBody, I as UserResourceList } from '../schema-BbKn_i-U.mjs';
5
3
 
6
4
  declare class UsersService {
7
5
  private core;
8
- constructor(core: CoreClient);
6
+ constructor(core: FetchClient);
9
7
  list(query?: UsersListQuery, init?: Omit<RequestInit, 'method' | 'body'>): Promise<UserList>;
10
8
  create(body: UserCreateBody, init?: Omit<RequestInit, 'method' | 'body'>): Promise<User>;
11
9
  delete(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown>;
@@ -1,11 +1,9 @@
1
- import { CoreClient } from '../client.js';
2
- import { A as UsersListQuery, D as UserList, F as UserCreateBody, G as User, H as UserUpdateBody, I as UserResourceList } from '../schema-B1usIXCr.js';
3
- import '@blimu/fetch';
4
- import '@blimu/types';
1
+ import { FetchClient } from '@blimu/fetch';
2
+ import { A as UsersListQuery, D as UserList, F as UserCreateBody, G as User, H as UserUpdateBody, I as UserResourceList } from '../schema-BbKn_i-U.js';
5
3
 
6
4
  declare class UsersService {
7
5
  private core;
8
- constructor(core: CoreClient);
6
+ constructor(core: FetchClient);
9
7
  list(query?: UsersListQuery, init?: Omit<RequestInit, 'method' | 'body'>): Promise<UserList>;
10
8
  create(body: UserCreateBody, init?: Omit<RequestInit, 'method' | 'body'>): Promise<User>;
11
9
  delete(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown>;
@@ -1,4 +1,5 @@
1
1
  // src/services/users.ts
2
+ import "@blimu/fetch";
2
3
  var UsersService = class {
3
4
  constructor(core) {
4
5
  this.core = core;
@@ -12,7 +13,7 @@ var UsersService = class {
12
13
  method: "GET",
13
14
  path: `/v1/users`,
14
15
  query,
15
- ...init || {}
16
+ ...init ?? {}
16
17
  });
17
18
  }
18
19
  /**
@@ -24,7 +25,7 @@ var UsersService = class {
24
25
  method: "POST",
25
26
  path: `/v1/users`,
26
27
  body,
27
- ...init || {}
28
+ ...init ?? {}
28
29
  });
29
30
  }
30
31
  /**
@@ -35,7 +36,7 @@ var UsersService = class {
35
36
  return this.core.request({
36
37
  method: "DELETE",
37
38
  path: `/v1/users/${encodeURIComponent(userId)}`,
38
- ...init || {}
39
+ ...init ?? {}
39
40
  });
40
41
  }
41
42
  /**
@@ -46,7 +47,7 @@ var UsersService = class {
46
47
  return this.core.request({
47
48
  method: "GET",
48
49
  path: `/v1/users/${encodeURIComponent(userId)}`,
49
- ...init || {}
50
+ ...init ?? {}
50
51
  });
51
52
  }
52
53
  /**
@@ -58,7 +59,7 @@ var UsersService = class {
58
59
  method: "PUT",
59
60
  path: `/v1/users/${encodeURIComponent(userId)}`,
60
61
  body,
61
- ...init || {}
62
+ ...init ?? {}
62
63
  });
63
64
  }
64
65
  /**
@@ -69,7 +70,7 @@ var UsersService = class {
69
70
  return this.core.request({
70
71
  method: "GET",
71
72
  path: `/v1/users/${encodeURIComponent(userId)}/effective-user-resources-roles`,
72
- ...init || {}
73
+ ...init ?? {}
73
74
  });
74
75
  }
75
76
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/users.ts"],"sourcesContent":["import { CoreClient } from '../client';\nimport * as Schema from '../schema';\n\nexport class UsersService {\n constructor(private core: CoreClient) {}\n\n /**\n * GET /v1/users*\n * @summary List users*\n * @description Retrieves a paginated list of users in your environment. Supports search functionality to filter users by email, name, or lookup key.*/\n list(\n query?: Schema.UsersListQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users`,\n query,\n ...(init || {}),\n });\n }\n\n /**\n * POST /v1/users*\n * @summary Create a user*\n * @description Creates a new user in your environment. The lookupKey is a unique identifier that you can use to reference the user in your system. It should be stable and not change over time.*/\n create(\n body: Schema.UserCreateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'POST',\n path: `/v1/users`,\n body: body as any,\n ...(init || {}),\n });\n }\n\n /**\n * DELETE /v1/users/{userId}*\n * @summary Delete a user*\n * @description Deletes a user by their ID or lookup key. This operation is permanent and cannot be undone. Deleting a user will also remove all role assignments for that user.*/\n delete(\n userId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<unknown> {\n return this.core.request({\n method: 'DELETE',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init || {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}*\n * @summary Get a user by ID*\n * @description Retrieves a single user by their ID or lookup key. Returns user information including email, name, and metadata.*/\n read(\n userId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init || {}),\n });\n }\n\n /**\n * PUT /v1/users/{userId}*\n * @summary Update a user*\n * @description Updates an existing user. You can modify email, name, and other user properties. The lookupKey can be updated but should remain stable.*/\n update(\n userId: string,\n body: Schema.UserUpdateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'PUT',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n body: body as any,\n ...(init || {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}/effective-user-resources-roles*\n * @summary List effective user resources roles*\n * @description Retrieves all resources and roles for a user, including inherited roles from parent resources. The response indicates whether each role is directly assigned or inherited through resource hierarchies.*/\n listEffectiveUserResourcesRoles(\n userId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserResourceList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}/effective-user-resources-roles`,\n ...(init || {}),\n });\n }\n}\n"],"mappings":";AAGO,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvC,KACE,OACA,MAC0B;AAC1B,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,QACA,MACkB;AAClB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KACE,QACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,QACA,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gCACE,QACA,MACkC;AAClC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/services/users.ts"],"sourcesContent":["import { FetchClient } from '@blimu/fetch';\nimport * as Schema from '../schema';\n\nexport class UsersService {\n constructor(private core: FetchClient) {}\n\n /**\n * GET /v1/users*\n * @summary List users*\n * @description Retrieves a paginated list of users in your environment. Supports search functionality to filter users by email, name, or lookup key.*/\n list(\n query?: Schema.UsersListQuery,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users`,\n query,\n ...(init ?? {}),\n });\n }\n\n /**\n * POST /v1/users*\n * @summary Create a user*\n * @description Creates a new user in your environment. The lookupKey is a unique identifier that you can use to reference the user in your system. It should be stable and not change over time.*/\n create(\n body: Schema.UserCreateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'POST',\n path: `/v1/users`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * DELETE /v1/users/{userId}*\n * @summary Delete a user*\n * @description Deletes a user by their ID or lookup key. This operation is permanent and cannot be undone. Deleting a user will also remove all role assignments for that user.*/\n delete(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<unknown> {\n return this.core.request({\n method: 'DELETE',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init ?? {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}*\n * @summary Get a user by ID*\n * @description Retrieves a single user by their ID or lookup key. Returns user information including email, name, and metadata.*/\n read(userId: string, init?: Omit<RequestInit, 'method' | 'body'>): Promise<Schema.User> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n ...(init ?? {}),\n });\n }\n\n /**\n * PUT /v1/users/{userId}*\n * @summary Update a user*\n * @description Updates an existing user. You can modify email, name, and other user properties. The lookupKey can be updated but should remain stable.*/\n update(\n userId: string,\n body: Schema.UserUpdateBody,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.User> {\n return this.core.request({\n method: 'PUT',\n path: `/v1/users/${encodeURIComponent(userId)}`,\n body,\n ...(init ?? {}),\n });\n }\n\n /**\n * GET /v1/users/{userId}/effective-user-resources-roles*\n * @summary List effective user resources roles*\n * @description Retrieves all resources and roles for a user, including inherited roles from parent resources. The response indicates whether each role is directly assigned or inherited through resource hierarchies.*/\n listEffectiveUserResourcesRoles(\n userId: string,\n init?: Omit<RequestInit, 'method' | 'body'>\n ): Promise<Schema.UserResourceList> {\n return this.core.request({\n method: 'GET',\n path: `/v1/users/${encodeURIComponent(userId)}/effective-user-resources-roles`,\n ...(init ?? {}),\n });\n }\n}\n"],"mappings":";AAAA,OAA4B;AAGrB,IAAM,eAAN,MAAmB;AAAA,EACxB,YAAoB,MAAmB;AAAnB;AAAA,EAAoB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,KACE,OACA,MAC0B;AAC1B,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAAgB,MAA+D;AACpF,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,QAAgB,MAAmE;AACtF,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OACE,QACA,MACA,MACsB;AACtB,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C;AAAA,MACA,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gCACE,QACA,MACkC;AAClC,WAAO,KAAK,KAAK,QAAQ;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,aAAa,mBAAmB,MAAM,CAAC;AAAA,MAC7C,GAAI,QAAQ,CAAC;AAAA,IACf,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -36,16 +37,18 @@ module.exports = __toCommonJS(token_verifier_exports);
36
37
 
37
38
  // src/client.ts
38
39
  var import_fetch = require("@blimu/fetch");
40
+ var import_fetch2 = require("@blimu/fetch");
39
41
 
40
42
  // src/token-verifier.ts
41
43
  var crypto = __toESM(require("crypto"));
42
44
  var jwt = __toESM(require("jsonwebtoken"));
43
45
  var TokenVerifier = class {
46
+ cache = /* @__PURE__ */ new Map();
47
+ cacheTTL;
48
+ runtimeApiUrl;
44
49
  constructor(options) {
45
- this.cache = /* @__PURE__ */ new Map();
46
50
  this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1e3;
47
- const blimuAuthApiUrl = typeof process !== "undefined" && process.env.BLIMU_AUTH_API_URL ? process.env.BLIMU_AUTH_API_URL : void 0;
48
- this.runtimeApiUrl = blimuAuthApiUrl ?? "https://api.blimu.dev";
51
+ this.runtimeApiUrl = options?.runtimeApiUrl ?? "https://api.blimu.dev";
49
52
  }
50
53
  /**
51
54
  * Fetch JWK Set from runtime-api
@@ -64,20 +67,14 @@ var TokenVerifier = class {
64
67
  ...headers
65
68
  }
66
69
  });
67
- console.log(
68
- `[TokenVerifier] \u{1F4E1} Response status: ${response.status} ${response.statusText}`
69
- );
70
+ console.log(`[TokenVerifier] \u{1F4E1} Response status: ${response.status} ${response.statusText}`);
70
71
  if (!response.ok) {
71
72
  const errorText = await response.text();
72
- console.error(
73
- `[TokenVerifier] \u274C Failed to fetch JWKs: ${response.status} ${errorText}`
74
- );
73
+ console.error(`[TokenVerifier] \u274C Failed to fetch JWKs: ${response.status} ${errorText}`);
75
74
  throw new import_fetch.FetchError("Failed to fetch JWKs", response.status, errorText);
76
75
  }
77
76
  const jwkSet = await response.json();
78
- console.log(
79
- `[TokenVerifier] \u2705 Successfully fetched JWK Set with ${jwkSet.keys.length} keys`
80
- );
77
+ console.log(`[TokenVerifier] \u2705 Successfully fetched JWK Set with ${jwkSet.keys.length} keys`);
81
78
  return jwkSet;
82
79
  }
83
80
  /**
@@ -103,9 +100,7 @@ var TokenVerifier = class {
103
100
  console.log(`[TokenVerifier] \u2705 Using cached key for kid: ${kid}`);
104
101
  return cached.key;
105
102
  }
106
- console.log(
107
- `[TokenVerifier] \u{1F50D} Cache miss or expired. Fetching new key for kid: ${kid}`
108
- );
103
+ console.log(`[TokenVerifier] \u{1F50D} Cache miss or expired. Fetching new key for kid: ${kid}`);
109
104
  const jwkSet = await this.fetchJWKSet(endpoint, headers);
110
105
  const jwk = jwkSet.keys.find((k) => k.kid === kid);
111
106
  if (!jwk) {
@@ -167,15 +162,8 @@ var TokenVerifier = class {
167
162
  }
168
163
  let publicKey;
169
164
  try {
170
- publicKey = await this.getPublicKey(
171
- header.kid,
172
- cacheKey,
173
- endpoint,
174
- headers
175
- );
176
- console.log(
177
- `[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid}`
178
- );
165
+ publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);
166
+ console.log(`[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid}`);
179
167
  } catch (error) {
180
168
  console.error(
181
169
  `[TokenVerifier] \u274C Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`
@@ -183,12 +171,7 @@ var TokenVerifier = class {
183
171
  this.clearCache(cacheKey);
184
172
  console.log(`[TokenVerifier] \u{1F504} Retrying after cache clear...`);
185
173
  try {
186
- publicKey = await this.getPublicKey(
187
- header.kid,
188
- cacheKey,
189
- endpoint,
190
- headers
191
- );
174
+ publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);
192
175
  console.log(
193
176
  `[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid} (retry)`
194
177
  );
@@ -232,4 +215,4 @@ async function verifyToken(options) {
232
215
  TokenVerifier,
233
216
  verifyToken
234
217
  });
235
- //# sourceMappingURL=token-verifier.js.map
218
+ //# sourceMappingURL=token-verifier.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/token-verifier.ts","../src/client.ts"],"sourcesContent":["import { FetchError } from './client';\nimport * as crypto from 'crypto';\nimport * as jwt from 'jsonwebtoken';\n\nexport interface JWK {\n kty: string;\n use: string;\n kid: string;\n alg: string;\n n: string;\n e: string;\n}\n\nexport interface JWKSet {\n keys: JWK[];\n}\n\ninterface CachedJWK {\n key: crypto.KeyObject;\n kid: string;\n expiresAt: number;\n}\n\nexport interface VerifyTokenOptions {\n url?: string; // Direct URL to JWK endpoint (for custom scenarios)\n secretKey?: string; // API key/secret key - uses runtimeApiUrl + JWK endpoint\n token: string;\n runtimeApiUrl?: string | undefined; // Optional override for runtime API URL\n}\n\nexport interface TokenVerifierOptions {\n runtimeApiUrl?: string | undefined;\n cacheTTL?: number | undefined; // Default: 1 hour\n}\n\nexport class TokenVerifier {\n private readonly cache = new Map<string, CachedJWK>();\n private readonly cacheTTL: number;\n private readonly runtimeApiUrl: string;\n\n constructor(options?: TokenVerifierOptions) {\n this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1000; // 1 hour\n\n this.runtimeApiUrl = options?.runtimeApiUrl ?? 'https://api.blimu.dev';\n }\n\n /**\n * Fetch JWK Set from runtime-api\n */\n private async fetchJWKSet(endpoint: string, headers?: Record<string, string>): Promise<JWKSet> {\n console.log(`[TokenVerifier] 📡 Fetching JWK Set from: ${endpoint}`);\n if (headers) {\n console.log(\n `[TokenVerifier] 📡 Request headers: ${JSON.stringify(Object.keys(headers).map((k) => `${k}: ${k === 'x-api-key' ? '***' : headers[k]}`))}`\n );\n }\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n console.log(`[TokenVerifier] 📡 Response status: ${response.status} ${response.statusText}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`[TokenVerifier] ❌ Failed to fetch JWKs: ${response.status} ${errorText}`);\n throw new FetchError('Failed to fetch JWKs', response.status, errorText);\n }\n\n const jwkSet = (await response.json()) as JWKSet;\n console.log(`[TokenVerifier] ✅ Successfully fetched JWK Set with ${jwkSet.keys.length} keys`);\n return jwkSet;\n }\n\n /**\n * Convert JWK to KeyObject\n */\n private jwkToKeyObject(jwk: JWK): crypto.KeyObject {\n return crypto.createPublicKey({\n key: {\n kty: jwk.kty,\n n: jwk.n,\n e: jwk.e,\n alg: jwk.alg,\n },\n format: 'jwk',\n });\n }\n\n /**\n * Get public key for a specific key ID\n */\n private async getPublicKey(\n kid: string,\n cacheKey: string,\n endpoint: string,\n headers?: Record<string, string>\n ): Promise<crypto.KeyObject> {\n // Check cache first\n const cached = this.cache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n console.log(`[TokenVerifier] ✅ Using cached key for kid: ${kid}`);\n return cached.key;\n }\n\n console.log(`[TokenVerifier] 🔍 Cache miss or expired. Fetching new key for kid: ${kid}`);\n\n // Fetch JWK Set\n const jwkSet = await this.fetchJWKSet(endpoint, headers);\n\n // Find the key with matching kid\n const jwk = jwkSet.keys.find((k) => k.kid === kid);\n if (!jwk) {\n const availableKids = jwkSet.keys.map((k) => k.kid).join(', ');\n console.error(\n `[TokenVerifier] ❌ Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n throw new Error(\n `Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n }\n\n console.log(`[TokenVerifier] ✅ Found key with kid: ${kid}`);\n\n // Convert JWK to KeyObject\n const keyObject = this.jwkToKeyObject(jwk);\n\n // Cache the key\n this.cache.set(cacheKey, {\n key: keyObject,\n kid,\n expiresAt: Date.now() + this.cacheTTL,\n });\n\n return keyObject;\n }\n\n /**\n * Verify JWT token using JWKs from runtime-api\n */\n async verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T> {\n const { url, secretKey, token, runtimeApiUrl } = options;\n\n if (!url && !secretKey) {\n throw new Error('Either url or secretKey must be provided');\n }\n\n if (url && secretKey) {\n throw new Error('Cannot provide both url and secretKey');\n }\n\n // Decode token header to get kid (without verification)\n const decoded = jwt.decode(token, { complete: true });\n if (!decoded || typeof decoded === 'string') {\n throw new Error('Invalid token format');\n }\n\n const header = decoded.header;\n if (!header.kid) {\n throw new Error('Token missing kid in header');\n }\n\n let endpoint: string;\n let cacheKey: string;\n let headers: Record<string, string> | undefined;\n\n if (secretKey) {\n // Use secretKey with runtimeApiUrl\n const apiUrl = runtimeApiUrl ?? this.runtimeApiUrl;\n endpoint = `${apiUrl}/v1/auth/.well-known/jwks.json`;\n cacheKey = secretKey;\n headers = {\n 'x-api-key': secretKey,\n };\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n } else {\n // Use direct URL\n endpoint = url!;\n cacheKey = url!;\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n }\n\n // Get public key for this kid\n let publicKey: crypto.KeyObject;\n try {\n publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);\n console.log(`[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid}`);\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`\n );\n // If verification fails, clear cache and retry once (handles key rotation)\n this.clearCache(cacheKey);\n console.log(`[TokenVerifier] 🔄 Retrying after cache clear...`);\n try {\n publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);\n console.log(\n `[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid} (retry)`\n );\n } catch (retryError) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (retry): ${retryError instanceof Error ? retryError.message : String(retryError)}`\n );\n throw retryError;\n }\n }\n\n // Verify token\n try {\n const payload = jwt.verify(token, publicKey, {\n algorithms: ['RS256'],\n }) as T;\n console.log(`[TokenVerifier] ✅ Token verified successfully`);\n return payload;\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ JWT verification failed: ${error instanceof Error ? error.message : String(error)}`\n );\n throw error;\n }\n }\n\n /**\n * Clear cache (useful for testing or key rotation)\n */\n clearCache(secretKeyOrUrl?: string): void {\n if (secretKeyOrUrl) {\n this.cache.delete(secretKeyOrUrl);\n } else {\n this.cache.clear();\n }\n }\n}\n\n/**\n * Convenience function to verify a token\n */\nexport async function verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T> {\n const verifier = new TokenVerifier();\n return verifier.verifyToken<T>(options);\n}\n","import { FetchClient, FetchError } from '@blimu/fetch';\nimport { type FetchClientConfig, type ApiKeyAuthStrategy } from '@blimu/fetch';\nimport { buildAuthStrategies } from './auth-strategies';\nimport { BulkResourcesService } from './services/bulk_resources';\nimport { BulkRolesService } from './services/bulk_roles';\nimport { EntitlementsService } from './services/entitlements';\nimport { PlansService } from './services/plans';\nimport { ResourceMembersService } from './services/resource_members';\nimport { ResourcesService } from './services/resources';\nimport { RolesService } from './services/roles';\nimport { UsageService } from './services/usage';\nimport { UsersService } from './services/users';\n\nexport type ClientOption = FetchClientConfig & {\n apiKey?: ApiKeyAuthStrategy['key'];\n};\n\nexport class Blimu {\n readonly bulkResources: BulkResourcesService;\n readonly bulkRoles: BulkRolesService;\n readonly entitlements: EntitlementsService;\n readonly plans: PlansService;\n readonly resourceMembers: ResourceMembersService;\n readonly resources: ResourcesService;\n readonly roles: RolesService;\n readonly usage: UsageService;\n readonly users: UsersService;\n\n constructor(options?: ClientOption) {\n const restCfg = { ...(options ?? {}) };\n delete restCfg.apiKey;\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.bulkResources = new BulkResourcesService(core);\n this.bulkRoles = new BulkRolesService(core);\n this.entitlements = new EntitlementsService(core);\n this.plans = new PlansService(core);\n this.resourceMembers = new ResourceMembersService(core);\n this.resources = new ResourcesService(core);\n this.roles = new RolesService(core);\n this.usage = new UsageService(core);\n this.users = new UsersService(core);\n }\n}\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\nexport const BlimuError = FetchError;\n"],"mappings":"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","names":["import_fetch"]}
@@ -13,11 +13,11 @@ interface VerifyTokenOptions {
13
13
  url?: string;
14
14
  secretKey?: string;
15
15
  token: string;
16
- runtimeApiUrl?: string;
16
+ runtimeApiUrl?: string | undefined;
17
17
  }
18
18
  interface TokenVerifierOptions {
19
- runtimeApiUrl?: string;
20
- cacheTTL?: number;
19
+ runtimeApiUrl?: string | undefined;
20
+ cacheTTL?: number | undefined;
21
21
  }
22
22
  declare class TokenVerifier {
23
23
  private readonly cache;
@@ -27,9 +27,9 @@ declare class TokenVerifier {
27
27
  private fetchJWKSet;
28
28
  private jwkToKeyObject;
29
29
  private getPublicKey;
30
- verifyToken<T = any>(options: VerifyTokenOptions): Promise<T>;
30
+ verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T>;
31
31
  clearCache(secretKeyOrUrl?: string): void;
32
32
  }
33
- declare function verifyToken<T = any>(options: VerifyTokenOptions): Promise<T>;
33
+ declare function verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T>;
34
34
 
35
35
  export { type JWK, type JWKSet, TokenVerifier, type TokenVerifierOptions, type VerifyTokenOptions, verifyToken };
@@ -13,11 +13,11 @@ interface VerifyTokenOptions {
13
13
  url?: string;
14
14
  secretKey?: string;
15
15
  token: string;
16
- runtimeApiUrl?: string;
16
+ runtimeApiUrl?: string | undefined;
17
17
  }
18
18
  interface TokenVerifierOptions {
19
- runtimeApiUrl?: string;
20
- cacheTTL?: number;
19
+ runtimeApiUrl?: string | undefined;
20
+ cacheTTL?: number | undefined;
21
21
  }
22
22
  declare class TokenVerifier {
23
23
  private readonly cache;
@@ -27,9 +27,9 @@ declare class TokenVerifier {
27
27
  private fetchJWKSet;
28
28
  private jwkToKeyObject;
29
29
  private getPublicKey;
30
- verifyToken<T = any>(options: VerifyTokenOptions): Promise<T>;
30
+ verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T>;
31
31
  clearCache(secretKeyOrUrl?: string): void;
32
32
  }
33
- declare function verifyToken<T = any>(options: VerifyTokenOptions): Promise<T>;
33
+ declare function verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T>;
34
34
 
35
35
  export { type JWK, type JWKSet, TokenVerifier, type TokenVerifierOptions, type VerifyTokenOptions, verifyToken };
@@ -1,18 +1,17 @@
1
1
  // src/client.ts
2
- import {
3
- FetchClient,
4
- FetchError
5
- } from "@blimu/fetch";
2
+ import { FetchClient, FetchError } from "@blimu/fetch";
3
+ import "@blimu/fetch";
6
4
 
7
5
  // src/token-verifier.ts
8
6
  import * as crypto from "crypto";
9
7
  import * as jwt from "jsonwebtoken";
10
8
  var TokenVerifier = class {
9
+ cache = /* @__PURE__ */ new Map();
10
+ cacheTTL;
11
+ runtimeApiUrl;
11
12
  constructor(options) {
12
- this.cache = /* @__PURE__ */ new Map();
13
13
  this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1e3;
14
- const blimuAuthApiUrl = typeof process !== "undefined" && process.env.BLIMU_AUTH_API_URL ? process.env.BLIMU_AUTH_API_URL : void 0;
15
- this.runtimeApiUrl = blimuAuthApiUrl ?? "https://api.blimu.dev";
14
+ this.runtimeApiUrl = options?.runtimeApiUrl ?? "https://api.blimu.dev";
16
15
  }
17
16
  /**
18
17
  * Fetch JWK Set from runtime-api
@@ -31,20 +30,14 @@ var TokenVerifier = class {
31
30
  ...headers
32
31
  }
33
32
  });
34
- console.log(
35
- `[TokenVerifier] \u{1F4E1} Response status: ${response.status} ${response.statusText}`
36
- );
33
+ console.log(`[TokenVerifier] \u{1F4E1} Response status: ${response.status} ${response.statusText}`);
37
34
  if (!response.ok) {
38
35
  const errorText = await response.text();
39
- console.error(
40
- `[TokenVerifier] \u274C Failed to fetch JWKs: ${response.status} ${errorText}`
41
- );
36
+ console.error(`[TokenVerifier] \u274C Failed to fetch JWKs: ${response.status} ${errorText}`);
42
37
  throw new FetchError("Failed to fetch JWKs", response.status, errorText);
43
38
  }
44
39
  const jwkSet = await response.json();
45
- console.log(
46
- `[TokenVerifier] \u2705 Successfully fetched JWK Set with ${jwkSet.keys.length} keys`
47
- );
40
+ console.log(`[TokenVerifier] \u2705 Successfully fetched JWK Set with ${jwkSet.keys.length} keys`);
48
41
  return jwkSet;
49
42
  }
50
43
  /**
@@ -70,9 +63,7 @@ var TokenVerifier = class {
70
63
  console.log(`[TokenVerifier] \u2705 Using cached key for kid: ${kid}`);
71
64
  return cached.key;
72
65
  }
73
- console.log(
74
- `[TokenVerifier] \u{1F50D} Cache miss or expired. Fetching new key for kid: ${kid}`
75
- );
66
+ console.log(`[TokenVerifier] \u{1F50D} Cache miss or expired. Fetching new key for kid: ${kid}`);
76
67
  const jwkSet = await this.fetchJWKSet(endpoint, headers);
77
68
  const jwk = jwkSet.keys.find((k) => k.kid === kid);
78
69
  if (!jwk) {
@@ -134,15 +125,8 @@ var TokenVerifier = class {
134
125
  }
135
126
  let publicKey;
136
127
  try {
137
- publicKey = await this.getPublicKey(
138
- header.kid,
139
- cacheKey,
140
- endpoint,
141
- headers
142
- );
143
- console.log(
144
- `[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid}`
145
- );
128
+ publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);
129
+ console.log(`[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid}`);
146
130
  } catch (error) {
147
131
  console.error(
148
132
  `[TokenVerifier] \u274C Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`
@@ -150,12 +134,7 @@ var TokenVerifier = class {
150
134
  this.clearCache(cacheKey);
151
135
  console.log(`[TokenVerifier] \u{1F504} Retrying after cache clear...`);
152
136
  try {
153
- publicKey = await this.getPublicKey(
154
- header.kid,
155
- cacheKey,
156
- endpoint,
157
- headers
158
- );
137
+ publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);
159
138
  console.log(
160
139
  `[TokenVerifier] \u2705 Successfully retrieved public key for kid: ${header.kid} (retry)`
161
140
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/token-verifier.ts"],"sourcesContent":["import {\n FetchClient,\n FetchError,\n type FetchClientConfig,\n type AuthStrategy,\n} from '@blimu/fetch';\n\nexport type ClientOption = FetchClientConfig & { apiKey?: string };\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\n\nexport class CoreClient extends FetchClient {\n constructor(cfg: ClientOption = {}) {\n // Build auth strategies from OpenAPI security schemes\n const authStrategies: AuthStrategy[] = [];\n\n // Extract auth and security scheme properties to avoid passing them to FetchClient\n const { auth: _existingAuth, apiKey, ...restCfg } = cfg;\n if (cfg?.apiKey) {\n const apiKeyValue = cfg.apiKey;\n authStrategies.push({\n type: 'apiKey',\n key: () => apiKeyValue,\n location: 'header',\n name: 'X-API-KEY',\n });\n } // Build final auth config (merge existing with new strategies)\n const finalAuthStrategies = [\n ...(_existingAuth?.strategies || []),\n ...authStrategies,\n ];\n\n // Build fetchConfig, ensuring auth comes after restCfg spread to override any existing auth\n const fetchConfig: FetchClientConfig = {\n ...restCfg,\n baseURL: cfg.baseURL ?? 'https://api.blimu.dev',\n // Explicitly set auth after restCfg to ensure it's not overwritten\n // (restCfg might have an auth property that we want to replace)\n ...(finalAuthStrategies.length > 0\n ? {\n auth: {\n strategies: finalAuthStrategies,\n },\n }\n : {}),\n // Hooks are passed through directly from FetchClientConfig (no mapping needed)\n };\n\n super(fetchConfig);\n }\n\n async request(\n init: RequestInit & {\n path: string;\n method: string;\n query?: Record<string, any>;\n }\n ) {\n return await super.request(init);\n }\n\n async *requestStream<T = any>(\n init: RequestInit & {\n path: string;\n method: string;\n query?: Record<string, any>;\n contentType: string;\n streamingFormat?: 'sse' | 'ndjson' | 'chunked';\n }\n ): AsyncGenerator<T, void, unknown> {\n yield* super.requestStream(init);\n }\n}\n","import { FetchError } from 'client';\nimport * as crypto from 'crypto';\nimport * as jwt from 'jsonwebtoken';\n\nexport interface JWK {\n kty: string;\n use: string;\n kid: string;\n alg: string;\n n: string;\n e: string;\n}\n\nexport interface JWKSet {\n keys: JWK[];\n}\n\ninterface CachedJWK {\n key: crypto.KeyObject;\n kid: string;\n expiresAt: number;\n}\n\nexport interface VerifyTokenOptions {\n url?: string; // Direct URL to JWK endpoint (for custom scenarios)\n secretKey?: string; // API key/secret key - uses runtimeApiUrl + JWK endpoint\n token: string;\n runtimeApiUrl?: string; // Optional override for runtime API URL\n}\n\nexport interface TokenVerifierOptions {\n runtimeApiUrl?: string; // Default from BLIMU_AUTH_API_URL env var\n cacheTTL?: number; // Default: 1 hour\n}\n\nexport class TokenVerifier {\n private readonly cache = new Map<string, CachedJWK>();\n private readonly cacheTTL: number;\n private readonly runtimeApiUrl: string;\n\n constructor(options?: TokenVerifierOptions) {\n this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1000; // 1 hour\n\n const blimuAuthApiUrl =\n typeof process !== 'undefined' && process.env.BLIMU_AUTH_API_URL\n ? process.env.BLIMU_AUTH_API_URL\n : undefined;\n\n // if we have secretKey, we can call runtime-api directly, otherwise we need to use customer specific auth-api\n this.runtimeApiUrl = blimuAuthApiUrl ?? 'https://api.blimu.dev';\n }\n\n /**\n * Fetch JWK Set from runtime-api\n */\n private async fetchJWKSet(\n endpoint: string,\n headers?: Record<string, string>\n ): Promise<JWKSet> {\n console.log(`[TokenVerifier] 📡 Fetching JWK Set from: ${endpoint}`);\n if (headers) {\n console.log(\n `[TokenVerifier] 📡 Request headers: ${JSON.stringify(Object.keys(headers).map((k) => `${k}: ${k === 'x-api-key' ? '***' : headers[k]}`))}`\n );\n }\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n console.log(\n `[TokenVerifier] 📡 Response status: ${response.status} ${response.statusText}`\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n `[TokenVerifier] ❌ Failed to fetch JWKs: ${response.status} ${errorText}`\n );\n throw new FetchError('Failed to fetch JWKs', response.status, errorText);\n }\n\n const jwkSet = (await response.json()) as JWKSet;\n console.log(\n `[TokenVerifier] ✅ Successfully fetched JWK Set with ${jwkSet.keys.length} keys`\n );\n return jwkSet;\n }\n\n /**\n * Convert JWK to KeyObject\n */\n private jwkToKeyObject(jwk: JWK): crypto.KeyObject {\n return crypto.createPublicKey({\n key: {\n kty: jwk.kty,\n n: jwk.n,\n e: jwk.e,\n alg: jwk.alg,\n },\n format: 'jwk',\n });\n }\n\n /**\n * Get public key for a specific key ID\n */\n private async getPublicKey(\n kid: string,\n cacheKey: string,\n endpoint: string,\n headers?: Record<string, string>\n ): Promise<crypto.KeyObject> {\n // Check cache first\n const cached = this.cache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n console.log(`[TokenVerifier] ✅ Using cached key for kid: ${kid}`);\n return cached.key;\n }\n\n console.log(\n `[TokenVerifier] 🔍 Cache miss or expired. Fetching new key for kid: ${kid}`\n );\n\n // Fetch JWK Set\n const jwkSet = await this.fetchJWKSet(endpoint, headers);\n\n // Find the key with matching kid\n const jwk = jwkSet.keys.find((k) => k.kid === kid);\n if (!jwk) {\n const availableKids = jwkSet.keys.map((k) => k.kid).join(', ');\n console.error(\n `[TokenVerifier] ❌ Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n throw new Error(\n `Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n }\n\n console.log(`[TokenVerifier] ✅ Found key with kid: ${kid}`);\n\n // Convert JWK to KeyObject\n const keyObject = this.jwkToKeyObject(jwk);\n\n // Cache the key\n this.cache.set(cacheKey, {\n key: keyObject,\n kid,\n expiresAt: Date.now() + this.cacheTTL,\n });\n\n return keyObject;\n }\n\n /**\n * Verify JWT token using JWKs from runtime-api\n */\n async verifyToken<T = any>(options: VerifyTokenOptions): Promise<T> {\n const { url, secretKey, token, runtimeApiUrl } = options;\n\n if (!url && !secretKey) {\n throw new Error('Either url or secretKey must be provided');\n }\n\n if (url && secretKey) {\n throw new Error('Cannot provide both url and secretKey');\n }\n\n // Decode token header to get kid (without verification)\n const decoded = jwt.decode(token, { complete: true });\n if (!decoded || typeof decoded === 'string') {\n throw new Error('Invalid token format');\n }\n\n const header = decoded.header;\n if (!header.kid) {\n throw new Error('Token missing kid in header');\n }\n\n let endpoint: string;\n let cacheKey: string;\n let headers: Record<string, string> | undefined;\n\n if (secretKey) {\n // Use secretKey with runtimeApiUrl\n const apiUrl = runtimeApiUrl ?? this.runtimeApiUrl;\n endpoint = `${apiUrl}/v1/auth/.well-known/jwks.json`;\n cacheKey = secretKey;\n headers = {\n 'x-api-key': secretKey,\n };\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n } else {\n // Use direct URL\n endpoint = url!;\n cacheKey = url!;\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n }\n\n // Get public key for this kid\n let publicKey: crypto.KeyObject;\n try {\n publicKey = await this.getPublicKey(\n header.kid,\n cacheKey,\n endpoint,\n headers\n );\n console.log(\n `[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid}`\n );\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`\n );\n // If verification fails, clear cache and retry once (handles key rotation)\n this.clearCache(cacheKey);\n console.log(`[TokenVerifier] 🔄 Retrying after cache clear...`);\n try {\n publicKey = await this.getPublicKey(\n header.kid,\n cacheKey,\n endpoint,\n headers\n );\n console.log(\n `[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid} (retry)`\n );\n } catch (retryError) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (retry): ${retryError instanceof Error ? retryError.message : String(retryError)}`\n );\n throw retryError;\n }\n }\n\n // Verify token\n try {\n const payload = jwt.verify(token, publicKey, {\n algorithms: ['RS256'],\n }) as T;\n console.log(`[TokenVerifier] ✅ Token verified successfully`);\n return payload;\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ JWT verification failed: ${error instanceof Error ? error.message : String(error)}`\n );\n throw error;\n }\n }\n\n /**\n * Clear cache (useful for testing or key rotation)\n */\n clearCache(secretKeyOrUrl?: string): void {\n if (secretKeyOrUrl) {\n this.cache.delete(secretKeyOrUrl);\n } else {\n this.cache.clear();\n }\n }\n}\n\n/**\n * Convenience function to verify a token\n */\nexport async function verifyToken<T = any>(\n options: VerifyTokenOptions\n): Promise<T> {\n const verifier = new TokenVerifier();\n return verifier.verifyToken<T>(options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/token-verifier.ts"],"sourcesContent":["import { FetchClient, FetchError } from '@blimu/fetch';\nimport { type FetchClientConfig, type ApiKeyAuthStrategy } from '@blimu/fetch';\nimport { buildAuthStrategies } from './auth-strategies';\nimport { BulkResourcesService } from './services/bulk_resources';\nimport { BulkRolesService } from './services/bulk_roles';\nimport { EntitlementsService } from './services/entitlements';\nimport { PlansService } from './services/plans';\nimport { ResourceMembersService } from './services/resource_members';\nimport { ResourcesService } from './services/resources';\nimport { RolesService } from './services/roles';\nimport { UsageService } from './services/usage';\nimport { UsersService } from './services/users';\n\nexport type ClientOption = FetchClientConfig & {\n apiKey?: ApiKeyAuthStrategy['key'];\n};\n\nexport class Blimu {\n readonly bulkResources: BulkResourcesService;\n readonly bulkRoles: BulkRolesService;\n readonly entitlements: EntitlementsService;\n readonly plans: PlansService;\n readonly resourceMembers: ResourceMembersService;\n readonly resources: ResourcesService;\n readonly roles: RolesService;\n readonly usage: UsageService;\n readonly users: UsersService;\n\n constructor(options?: ClientOption) {\n const restCfg = { ...(options ?? {}) };\n delete restCfg.apiKey;\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.bulkResources = new BulkResourcesService(core);\n this.bulkRoles = new BulkRolesService(core);\n this.entitlements = new EntitlementsService(core);\n this.plans = new PlansService(core);\n this.resourceMembers = new ResourceMembersService(core);\n this.resources = new ResourcesService(core);\n this.roles = new RolesService(core);\n this.usage = new UsageService(core);\n this.users = new UsersService(core);\n }\n}\n\n// Re-export FetchError for backward compatibility\nexport { FetchError };\nexport const BlimuError = FetchError;\n","import { FetchError } from './client';\nimport * as crypto from 'crypto';\nimport * as jwt from 'jsonwebtoken';\n\nexport interface JWK {\n kty: string;\n use: string;\n kid: string;\n alg: string;\n n: string;\n e: string;\n}\n\nexport interface JWKSet {\n keys: JWK[];\n}\n\ninterface CachedJWK {\n key: crypto.KeyObject;\n kid: string;\n expiresAt: number;\n}\n\nexport interface VerifyTokenOptions {\n url?: string; // Direct URL to JWK endpoint (for custom scenarios)\n secretKey?: string; // API key/secret key - uses runtimeApiUrl + JWK endpoint\n token: string;\n runtimeApiUrl?: string | undefined; // Optional override for runtime API URL\n}\n\nexport interface TokenVerifierOptions {\n runtimeApiUrl?: string | undefined;\n cacheTTL?: number | undefined; // Default: 1 hour\n}\n\nexport class TokenVerifier {\n private readonly cache = new Map<string, CachedJWK>();\n private readonly cacheTTL: number;\n private readonly runtimeApiUrl: string;\n\n constructor(options?: TokenVerifierOptions) {\n this.cacheTTL = options?.cacheTTL ?? 60 * 60 * 1000; // 1 hour\n\n this.runtimeApiUrl = options?.runtimeApiUrl ?? 'https://api.blimu.dev';\n }\n\n /**\n * Fetch JWK Set from runtime-api\n */\n private async fetchJWKSet(endpoint: string, headers?: Record<string, string>): Promise<JWKSet> {\n console.log(`[TokenVerifier] 📡 Fetching JWK Set from: ${endpoint}`);\n if (headers) {\n console.log(\n `[TokenVerifier] 📡 Request headers: ${JSON.stringify(Object.keys(headers).map((k) => `${k}: ${k === 'x-api-key' ? '***' : headers[k]}`))}`\n );\n }\n\n const response = await fetch(endpoint, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n });\n\n console.log(`[TokenVerifier] 📡 Response status: ${response.status} ${response.statusText}`);\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(`[TokenVerifier] ❌ Failed to fetch JWKs: ${response.status} ${errorText}`);\n throw new FetchError('Failed to fetch JWKs', response.status, errorText);\n }\n\n const jwkSet = (await response.json()) as JWKSet;\n console.log(`[TokenVerifier] ✅ Successfully fetched JWK Set with ${jwkSet.keys.length} keys`);\n return jwkSet;\n }\n\n /**\n * Convert JWK to KeyObject\n */\n private jwkToKeyObject(jwk: JWK): crypto.KeyObject {\n return crypto.createPublicKey({\n key: {\n kty: jwk.kty,\n n: jwk.n,\n e: jwk.e,\n alg: jwk.alg,\n },\n format: 'jwk',\n });\n }\n\n /**\n * Get public key for a specific key ID\n */\n private async getPublicKey(\n kid: string,\n cacheKey: string,\n endpoint: string,\n headers?: Record<string, string>\n ): Promise<crypto.KeyObject> {\n // Check cache first\n const cached = this.cache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n console.log(`[TokenVerifier] ✅ Using cached key for kid: ${kid}`);\n return cached.key;\n }\n\n console.log(`[TokenVerifier] 🔍 Cache miss or expired. Fetching new key for kid: ${kid}`);\n\n // Fetch JWK Set\n const jwkSet = await this.fetchJWKSet(endpoint, headers);\n\n // Find the key with matching kid\n const jwk = jwkSet.keys.find((k) => k.kid === kid);\n if (!jwk) {\n const availableKids = jwkSet.keys.map((k) => k.kid).join(', ');\n console.error(\n `[TokenVerifier] ❌ Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n throw new Error(\n `Key with kid '${kid}' not found in JWK Set. Available kids: ${availableKids}`\n );\n }\n\n console.log(`[TokenVerifier] ✅ Found key with kid: ${kid}`);\n\n // Convert JWK to KeyObject\n const keyObject = this.jwkToKeyObject(jwk);\n\n // Cache the key\n this.cache.set(cacheKey, {\n key: keyObject,\n kid,\n expiresAt: Date.now() + this.cacheTTL,\n });\n\n return keyObject;\n }\n\n /**\n * Verify JWT token using JWKs from runtime-api\n */\n async verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T> {\n const { url, secretKey, token, runtimeApiUrl } = options;\n\n if (!url && !secretKey) {\n throw new Error('Either url or secretKey must be provided');\n }\n\n if (url && secretKey) {\n throw new Error('Cannot provide both url and secretKey');\n }\n\n // Decode token header to get kid (without verification)\n const decoded = jwt.decode(token, { complete: true });\n if (!decoded || typeof decoded === 'string') {\n throw new Error('Invalid token format');\n }\n\n const header = decoded.header;\n if (!header.kid) {\n throw new Error('Token missing kid in header');\n }\n\n let endpoint: string;\n let cacheKey: string;\n let headers: Record<string, string> | undefined;\n\n if (secretKey) {\n // Use secretKey with runtimeApiUrl\n const apiUrl = runtimeApiUrl ?? this.runtimeApiUrl;\n endpoint = `${apiUrl}/v1/auth/.well-known/jwks.json`;\n cacheKey = secretKey;\n headers = {\n 'x-api-key': secretKey,\n };\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n } else {\n // Use direct URL\n endpoint = url!;\n cacheKey = url!;\n console.log(\n `[TokenVerifier] 🔍 Verifying token with kid: ${header.kid}, endpoint: ${endpoint}`\n );\n }\n\n // Get public key for this kid\n let publicKey: crypto.KeyObject;\n try {\n publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);\n console.log(`[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid}`);\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (first attempt): ${error instanceof Error ? error.message : String(error)}`\n );\n // If verification fails, clear cache and retry once (handles key rotation)\n this.clearCache(cacheKey);\n console.log(`[TokenVerifier] 🔄 Retrying after cache clear...`);\n try {\n publicKey = await this.getPublicKey(header.kid, cacheKey, endpoint, headers);\n console.log(\n `[TokenVerifier] ✅ Successfully retrieved public key for kid: ${header.kid} (retry)`\n );\n } catch (retryError) {\n console.error(\n `[TokenVerifier] ❌ Failed to get public key (retry): ${retryError instanceof Error ? retryError.message : String(retryError)}`\n );\n throw retryError;\n }\n }\n\n // Verify token\n try {\n const payload = jwt.verify(token, publicKey, {\n algorithms: ['RS256'],\n }) as T;\n console.log(`[TokenVerifier] ✅ Token verified successfully`);\n return payload;\n } catch (error) {\n console.error(\n `[TokenVerifier] ❌ JWT verification failed: ${error instanceof Error ? error.message : String(error)}`\n );\n throw error;\n }\n }\n\n /**\n * Clear cache (useful for testing or key rotation)\n */\n clearCache(secretKeyOrUrl?: string): void {\n if (secretKeyOrUrl) {\n this.cache.delete(secretKeyOrUrl);\n } else {\n this.cache.clear();\n }\n }\n}\n\n/**\n * Convenience function to verify a token\n */\nexport async function verifyToken<T = unknown>(options: VerifyTokenOptions): Promise<T> {\n const verifier = new TokenVerifier();\n return verifier.verifyToken<T>(options);\n}\n"],"mappings":"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","names":[]}