@bloque/sdk-core 0.0.20 → 0.0.21

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.
@@ -4,7 +4,8 @@ export declare class HttpClient {
4
4
  private readonly baseUrl;
5
5
  private readonly publicRoutes;
6
6
  constructor(config: BloqueConfig);
7
- private isPublicRoute;
8
7
  private validateConfig;
8
+ private isPublicRoute;
9
+ private buildAuthHeaders;
9
10
  request<T, U = unknown>(options: RequestOptions<U>): Promise<T>;
10
11
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,r)=>{for(var o in r)__webpack_require__.o(r,o)&&!__webpack_require__.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},__webpack_require__.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{API_BASE_URLS:()=>API_BASE_URLS,DEFAULT_HEADERS:()=>DEFAULT_HEADERS,HttpClient:()=>HttpClient,BloqueAPIError:()=>BloqueAPIError,BloqueConfigError:()=>BloqueConfigError});const API_BASE_URLS={sandbox:"https://dev.bloque.app",production:"https://api.bloque.app"},DEFAULT_HEADERS={"Content-Type":"application/json"};class BloqueAPIError extends Error{status;code;constructor(e,r,o){super(e),this.name="BloqueAPIError",this.status=r,this.code=o,Object.setPrototypeOf(this,BloqueAPIError.prototype)}}class BloqueConfigError extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,BloqueConfigError.prototype)}}const createLocalStorageAdapter=()=>({get:()=>"u"<typeof localStorage?null:localStorage.getItem("access_token"),set:e=>{"u">typeof localStorage&&localStorage.setItem("access_token",e)},clear:()=>{"u">typeof localStorage&&localStorage.removeItem("access_token")}});class HttpClient{config;baseUrl;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins"];constructor(e){this.validateConfig(e),this.config=e,this.baseUrl=API_BASE_URLS[e.mode??"production"]}isPublicRoute(e){let r=e.split("?")[0];return this.publicRoutes.some(e=>{let o=e.replace(/\*/g,"[^/]+");return RegExp(`^${o}$`).test(r)})}validateConfig(e){if(!e.apiKey||""===e.apiKey.trim())throw new BloqueConfigError("API key is required");if(e.mode||(e.mode="production"),!["sandbox","production"].includes(e.mode))throw new BloqueConfigError('Mode must be either "sandbox" or "production"');"client"!==e.runtime||e.tokenStorage||(e.tokenStorage=createLocalStorageAdapter())}async request(e){let{method:r,path:o,body:t,headers:_={}}=e,i=`${this.baseUrl}${o}`,s={...DEFAULT_HEADERS,Authorization:this.config.apiKey,..._};if("client"===this.config.runtime&&!this.isPublicRoute(o)){let e=this.config.tokenStorage?.get();if(!e)throw new BloqueConfigError("Authentication token is missing");s.Authorization=`Bearer ${e}`}try{let e=await fetch(i,{method:r,headers:s,body:t?JSON.stringify(t):void 0}),o=await e.json().catch(()=>({}));if(!e.ok)throw new BloqueAPIError(o.message||`HTTP ${e.status}: ${e.statusText}`,e.status,o.code);return o}catch(e){if(e instanceof BloqueAPIError)throw e;if(e instanceof Error)throw new BloqueAPIError(`Request failed: ${e.message}`,void 0,"NETWORK_ERROR");throw new BloqueAPIError("Unknown error occurred",void 0,"UNKNOWN_ERROR")}}}for(var __rspack_i in exports.API_BASE_URLS=__webpack_exports__.API_BASE_URLS,exports.BloqueAPIError=__webpack_exports__.BloqueAPIError,exports.BloqueConfigError=__webpack_exports__.BloqueConfigError,exports.DEFAULT_HEADERS=__webpack_exports__.DEFAULT_HEADERS,exports.HttpClient=__webpack_exports__.HttpClient,__webpack_exports__)-1===["API_BASE_URLS","BloqueAPIError","BloqueConfigError","DEFAULT_HEADERS","HttpClient"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
1
+ "use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,r)=>{for(var t in r)__webpack_require__.o(r,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},__webpack_require__.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{API_BASE_URLS:()=>API_BASE_URLS,DEFAULT_HEADERS:()=>DEFAULT_HEADERS,HttpClient:()=>HttpClient,BloqueAPIError:()=>BloqueAPIError,BloqueConfigError:()=>BloqueConfigError});const API_BASE_URLS={sandbox:"https://dev.bloque.app",production:"https://api.bloque.app"},DEFAULT_HEADERS={"Content-Type":"application/json"};class BloqueAPIError extends Error{status;code;constructor(e,r,t){super(e),this.name="BloqueAPIError",this.status=r,this.code=t,Object.setPrototypeOf(this,BloqueAPIError.prototype)}}class BloqueConfigError extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,BloqueConfigError.prototype)}}const isFrontendPlatform=e=>"browser"===e||"react-native"===e,createLocalStorageAdapter=()=>({get:()=>"u"<typeof localStorage?null:localStorage.getItem("access_token"),set:e=>{"u">typeof localStorage&&localStorage.setItem("access_token",e)},clear:()=>{"u">typeof localStorage&&localStorage.removeItem("access_token")}});class HttpClient{config;baseUrl;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins"];constructor(e){this.validateConfig(e),this.config=e,this.baseUrl=API_BASE_URLS[e.mode??"production"]}validateConfig(e){if(e.mode??="production",e.platform??="node",!["sandbox","production"].includes(e.mode))throw new BloqueConfigError('Mode must be either "sandbox" or "production"');if("apiKey"===e.auth.type){if(!e.auth.apiKey?.trim())throw new BloqueConfigError("API key is required for apiKey authentication");if(isFrontendPlatform(e.platform))throw new BloqueConfigError("API key authentication is not allowed in frontend platforms")}if("jwt"===e.auth.type&&!e.tokenStorage)if("browser"===e.platform)e.tokenStorage=createLocalStorageAdapter();else throw new BloqueConfigError("tokenStorage must be provided when using JWT authentication")}isPublicRoute(e){let r=e.split("?")[0];return this.publicRoutes.some(e=>{let t=e.replace(/\*/g,"[^/]+");return RegExp(`^${t}$`).test(r)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this.config.auth.type)return{Authorization:this.config.auth.apiKey};if("jwt"===this.config.auth.type){let e=this.config.tokenStorage?.get();if(!e)throw new BloqueConfigError("Authentication token is missing");return{Authorization:`Bearer ${e}`}}return{}}async request(e){let{method:r,path:t,body:o,headers:i={}}=e,a=`${this.baseUrl}${t}`,_={...DEFAULT_HEADERS,...this.buildAuthHeaders(t),...i};try{let e=await fetch(a,{method:r,headers:_,body:o?JSON.stringify(o):void 0}),t=await e.json().catch(()=>({}));if(!e.ok)throw new BloqueAPIError(t.message||`HTTP ${e.status}: ${e.statusText}`,e.status,t.code);return t}catch(e){if(e instanceof BloqueAPIError)throw e;if(e instanceof Error)throw new BloqueAPIError(`Request failed: ${e.message}`,void 0,"NETWORK_ERROR");throw new BloqueAPIError("Unknown error occurred",void 0,"UNKNOWN_ERROR")}}}for(var __rspack_i in exports.API_BASE_URLS=__webpack_exports__.API_BASE_URLS,exports.BloqueAPIError=__webpack_exports__.BloqueAPIError,exports.BloqueConfigError=__webpack_exports__.BloqueConfigError,exports.DEFAULT_HEADERS=__webpack_exports__.DEFAULT_HEADERS,exports.HttpClient=__webpack_exports__.HttpClient,__webpack_exports__)-1===["API_BASE_URLS","BloqueAPIError","BloqueConfigError","DEFAULT_HEADERS","HttpClient"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- let t={sandbox:"https://dev.bloque.app",production:"https://api.bloque.app"},e={"Content-Type":"application/json"};class o extends Error{status;code;constructor(t,e,r){super(t),this.name="BloqueAPIError",this.status=e,this.code=r,Object.setPrototypeOf(this,o.prototype)}}class r extends Error{constructor(t){super(t),this.name="BloqueConfigError",Object.setPrototypeOf(this,r.prototype)}}class i{config;baseUrl;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins"];constructor(e){this.validateConfig(e),this.config=e,this.baseUrl=t[e.mode??"production"]}isPublicRoute(t){let e=t.split("?")[0];return this.publicRoutes.some(t=>{let o=t.replace(/\*/g,"[^/]+");return RegExp(`^${o}$`).test(e)})}validateConfig(t){if(!t.apiKey||""===t.apiKey.trim())throw new r("API key is required");if(t.mode||(t.mode="production"),!["sandbox","production"].includes(t.mode))throw new r('Mode must be either "sandbox" or "production"');"client"!==t.runtime||t.tokenStorage||(t.tokenStorage={get:()=>"u"<typeof localStorage?null:localStorage.getItem("access_token"),set:t=>{"u">typeof localStorage&&localStorage.setItem("access_token",t)},clear:()=>{"u">typeof localStorage&&localStorage.removeItem("access_token")}})}async request(t){let{method:i,path:s,body:a,headers:n={}}=t,c=`${this.baseUrl}${s}`,l={...e,Authorization:this.config.apiKey,...n};if("client"===this.config.runtime&&!this.isPublicRoute(s)){let t=this.config.tokenStorage?.get();if(!t)throw new r("Authentication token is missing");l.Authorization=`Bearer ${t}`}try{let t=await fetch(c,{method:i,headers:l,body:a?JSON.stringify(a):void 0}),e=await t.json().catch(()=>({}));if(!t.ok)throw new o(e.message||`HTTP ${t.status}: ${t.statusText}`,t.status,e.code);return e}catch(t){if(t instanceof o)throw t;if(t instanceof Error)throw new o(`Request failed: ${t.message}`,void 0,"NETWORK_ERROR");throw new o("Unknown error occurred",void 0,"UNKNOWN_ERROR")}}}export{t as API_BASE_URLS,o as BloqueAPIError,r as BloqueConfigError,e as DEFAULT_HEADERS,i as HttpClient};
1
+ let t={sandbox:"https://dev.bloque.app",production:"https://api.bloque.app"},e={"Content-Type":"application/json"};class o extends Error{status;code;constructor(t,e,r){super(t),this.name="BloqueAPIError",this.status=e,this.code=r,Object.setPrototypeOf(this,o.prototype)}}class r extends Error{constructor(t){super(t),this.name="BloqueConfigError",Object.setPrototypeOf(this,r.prototype)}}class i{config;baseUrl;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins"];constructor(e){this.validateConfig(e),this.config=e,this.baseUrl=t[e.mode??"production"]}validateConfig(t){if(t.mode??="production",t.platform??="node",!["sandbox","production"].includes(t.mode))throw new r('Mode must be either "sandbox" or "production"');if("apiKey"===t.auth.type){let e;if(!t.auth.apiKey?.trim())throw new r("API key is required for apiKey authentication");if("browser"===(e=t.platform)||"react-native"===e)throw new r("API key authentication is not allowed in frontend platforms")}if("jwt"===t.auth.type&&!t.tokenStorage)if("browser"===t.platform)t.tokenStorage={get:()=>"u"<typeof localStorage?null:localStorage.getItem("access_token"),set:t=>{"u">typeof localStorage&&localStorage.setItem("access_token",t)},clear:()=>{"u">typeof localStorage&&localStorage.removeItem("access_token")}};else throw new r("tokenStorage must be provided when using JWT authentication")}isPublicRoute(t){let e=t.split("?")[0];return this.publicRoutes.some(t=>{let o=t.replace(/\*/g,"[^/]+");return RegExp(`^${o}$`).test(e)})}buildAuthHeaders(t){if(this.isPublicRoute(t))return{};if("apiKey"===this.config.auth.type)return{Authorization:this.config.auth.apiKey};if("jwt"===this.config.auth.type){let t=this.config.tokenStorage?.get();if(!t)throw new r("Authentication token is missing");return{Authorization:`Bearer ${t}`}}return{}}async request(t){let{method:r,path:i,body:s,headers:a={}}=t,n=`${this.baseUrl}${i}`,u={...e,...this.buildAuthHeaders(i),...a};try{let t=await fetch(n,{method:r,headers:u,body:s?JSON.stringify(s):void 0}),e=await t.json().catch(()=>({}));if(!t.ok)throw new o(e.message||`HTTP ${t.status}: ${t.statusText}`,t.status,e.code);return e}catch(t){if(t instanceof o)throw t;if(t instanceof Error)throw new o(`Request failed: ${t.message}`,void 0,"NETWORK_ERROR");throw new o("Unknown error occurred",void 0,"UNKNOWN_ERROR")}}}export{t as API_BASE_URLS,o as BloqueAPIError,r as BloqueConfigError,e as DEFAULT_HEADERS,i as HttpClient};
package/dist/types.d.ts CHANGED
@@ -12,32 +12,68 @@ export type Mode =
12
12
  * Uses isolated endpoints and mock data for development and testing.
13
13
  */
14
14
  | 'sandbox';
15
- export type Runtime =
15
+ export type Platform =
16
16
  /**
17
- * Server runtime (default).
17
+ * Node.js runtime.
18
18
  *
19
- * Intended for backend environments such as Node.js, Bun,
20
- * Deno, Edge runtimes, or any server-side execution context.
19
+ * Intended for backend environments running on Node.js.
21
20
  *
22
- * Allows the use of private API keys.
21
+ * Typical use cases:
22
+ * - APIs
23
+ * - Backend services
24
+ * - Server-side workers
25
+ *
26
+ * Supports the use of private API keys.
27
+ */
28
+ 'node'
29
+ /**
30
+ * Deno runtime.
31
+ *
32
+ * Intended for backend environments running on Deno.
33
+ *
34
+ * Typical use cases:
35
+ * - Serverless functions
36
+ * - Edge-like services
37
+ *
38
+ * Supports the use of private API keys.
39
+ */
40
+ | 'deno'
41
+ /**
42
+ * Bun runtime.
43
+ *
44
+ * Intended for backend environments running on Bun.
45
+ *
46
+ * Typical use cases:
47
+ * - High-performance backend services
48
+ * - Local development servers
49
+ *
50
+ * Supports the use of private API keys.
23
51
  */
24
- 'server'
52
+ | 'bun'
25
53
  /**
26
- * Client runtime.
54
+ * Browser runtime.
27
55
  *
28
- * Intended for browsers or frontend runtimes.
56
+ * Intended for web browsers and browser-like environments.
57
+ *
58
+ * Characteristics:
59
+ * - No access to private API keys
60
+ * - Authentication is performed via JWT
61
+ * - Token persistence must be explicitly configured
62
+ * (e.g. localStorage, sessionStorage, in-memory)
63
+ */
64
+ | 'browser'
65
+ /**
66
+ * React Native runtime.
29
67
  *
30
- * In the current version of the SDK:
31
- * - The client authenticates using the `auth` module.
32
- * - The SDK automatically obtains and manages a JWT.
33
- * - The JWT is used to authenticate all subsequent requests.
34
- * - An authenticated client can execute any operation
35
- * exposed by the API.
68
+ * Intended for React Native applications (iOS / Android).
36
69
  *
37
- * Authorization and security enforcement are handled
38
- * exclusively by the backend.
70
+ * Characteristics:
71
+ * - No access to private API keys
72
+ * - Authentication is performed via JWT
73
+ * - Token persistence must be provided by the consumer
74
+ * (e.g. AsyncStorage, secure storage, in-memory)
39
75
  */
40
- | 'client';
76
+ | 'react-native';
41
77
  /**
42
78
  * Interface that defines how the SDK stores and retrieves
43
79
  * the JWT token when running in `client` runtime.
@@ -63,6 +99,12 @@ export interface TokenStorage {
63
99
  */
64
100
  clear(): void;
65
101
  }
102
+ export type AuthStrategy = {
103
+ type: 'apiKey';
104
+ apiKey: string;
105
+ } | {
106
+ type: 'jwt';
107
+ };
66
108
  /**
67
109
  * Main configuration object for the Bloque SDK.
68
110
  *
@@ -71,13 +113,34 @@ export interface TokenStorage {
71
113
  */
72
114
  export interface BloqueConfig {
73
115
  /**
74
- * Bloque API key.
116
+ * Platform where the SDK is executed.
117
+ *
118
+ * Determines the runtime environment and its capabilities.
119
+ *
120
+ * - `node` (default): backend runtime (Node.js, Bun, Deno).
121
+ * Supports authentication using private API keys.
122
+ *
123
+ * - `browser`: web browser environment.
124
+ * Does not allow private API keys.
125
+ * Authentication must be performed using JWT.
75
126
  *
76
- * - In `server` runtime, a private API key is expected.
77
- * - In `client` runtime, the API key is not used directly;
78
- * authentication is performed via JWT instead.
127
+ * - `react-native`: React Native environment (iOS / Android).
128
+ * Does not allow private API keys.
129
+ * Authentication must be performed using JWT.
130
+ *
131
+ * If not specified, the SDK defaults to `node`.
79
132
  */
80
- apiKey: string;
133
+ platform?: Platform;
134
+ /**
135
+ * Authentication strategy used by the SDK.
136
+ *
137
+ * - `apiKey`: intended for backend platforms (`node`, `bun`, `deno`).
138
+ * - `jwt`: intended for frontend platforms (`browser`, `react-native`).
139
+ *
140
+ * The SDK validates the compatibility between the selected
141
+ * platform and the authentication strategy at runtime.
142
+ */
143
+ auth: AuthStrategy;
81
144
  /**
82
145
  * SDK operation mode.
83
146
  *
@@ -87,15 +150,6 @@ export interface BloqueConfig {
87
150
  * If not specified, the SDK defaults to `production`.
88
151
  */
89
152
  mode?: Mode;
90
- /**
91
- * Runtime environment where the SDK is executed.
92
- *
93
- * - `server` (default): backend runtime using API keys.
94
- * - `client`: frontend runtime using JWT authentication.
95
- *
96
- * If not specified, the SDK defaults to `server`.
97
- */
98
- runtime?: 'server' | 'client';
99
153
  /**
100
154
  * JWT token storage strategy.
101
155
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bloque/sdk-core",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "Core utilities and types for Bloque SDK.",
5
5
  "type": "module",
6
6
  "keywords": [