@bloque/sdk-core 0.0.20 → 0.0.22

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.
@@ -0,0 +1,5 @@
1
+ import type { HttpClient } from './http-client';
2
+ export declare abstract class BaseClient {
3
+ protected readonly httpClient: HttpClient;
4
+ constructor(httpClient: HttpClient);
5
+ }
@@ -1,10 +1,11 @@
1
1
  import type { BloqueConfig, RequestOptions } from './types';
2
2
  export declare class HttpClient {
3
- private readonly config;
3
+ readonly config: BloqueConfig;
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,t)=>{for(var r in t)__webpack_require__.o(t,r)&&!__webpack_require__.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__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,BaseClient:()=>BaseClient,DEFAULT_HEADERS:()=>DEFAULT_HEADERS,BloqueAPIError:()=>BloqueAPIError,BloqueConfigError:()=>BloqueConfigError,HttpClient:()=>HttpClient});class BaseClient{httpClient;constructor(e){this.httpClient=e}}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,t,r){super(e),this.name="BloqueAPIError",this.status=t,this.code=r,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 t=e.split("?")[0];return this.publicRoutes.some(e=>{let r=e.replace(/\*/g,"[^/]+");return RegExp(`^${r}$`).test(t)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this.config.auth.type)return this.config.accessToken?{Authorization:`Bearer ${this.config.accessToken}`}:{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:t,path:r,body:o,headers:i={}}=e,a=`${this.baseUrl}${r}`,s={...DEFAULT_HEADERS,...this.buildAuthHeaders(r),...i};try{let e=await fetch(a,{method:t,headers:s,body:o?JSON.stringify(o):void 0}),r=await e.json().catch(()=>({}));if(!e.ok)throw new BloqueAPIError(r.message||`HTTP ${e.status}: ${e.statusText}`,e.status,r.code);return r}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.BaseClient=__webpack_exports__.BaseClient,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","BaseClient","BloqueAPIError","BloqueConfigError","DEFAULT_HEADERS","HttpClient"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './base-client';
1
2
  export * from './constants';
2
3
  export * from './errors';
3
4
  export * from './http-client';
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
+ class t{httpClient;constructor(t){this.httpClient=t}}let e={sandbox:"https://dev.bloque.app",production:"https://api.bloque.app"},o={"Content-Type":"application/json"};class r extends Error{status;code;constructor(t,e,o){super(t),this.name="BloqueAPIError",this.status=e,this.code=o,Object.setPrototypeOf(this,r.prototype)}}class i extends Error{constructor(t){super(t),this.name="BloqueConfigError",Object.setPrototypeOf(this,i.prototype)}}class s{config;baseUrl;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins"];constructor(t){this.validateConfig(t),this.config=t,this.baseUrl=e[t.mode??"production"]}validateConfig(t){if(t.mode??="production",t.platform??="node",!["sandbox","production"].includes(t.mode))throw new i('Mode must be either "sandbox" or "production"');if("apiKey"===t.auth.type){let e;if(!t.auth.apiKey?.trim())throw new i("API key is required for apiKey authentication");if("browser"===(e=t.platform)||"react-native"===e)throw new i("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 i("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 this.config.accessToken?{Authorization:`Bearer ${this.config.accessToken}`}:{Authorization:this.config.auth.apiKey};if("jwt"===this.config.auth.type){let t=this.config.tokenStorage?.get();if(!t)throw new i("Authentication token is missing");return{Authorization:`Bearer ${t}`}}return{}}async request(t){let{method:e,path:i,body:s,headers:a={}}=t,n=`${this.baseUrl}${i}`,c={...o,...this.buildAuthHeaders(i),...a};try{let t=await fetch(n,{method:e,headers:c,body:s?JSON.stringify(s):void 0}),o=await t.json().catch(()=>({}));if(!t.ok)throw new r(o.message||`HTTP ${t.status}: ${t.statusText}`,t.status,o.code);return o}catch(t){if(t instanceof r)throw t;if(t instanceof Error)throw new r(`Request failed: ${t.message}`,void 0,"NETWORK_ERROR");throw new r("Unknown error occurred",void 0,"UNKNOWN_ERROR")}}}export{e as API_BASE_URLS,t as BaseClient,r as BloqueAPIError,i as BloqueConfigError,o as DEFAULT_HEADERS,s 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.
23
27
  */
24
- 'server'
28
+ 'node'
25
29
  /**
26
- * Client runtime.
30
+ * Deno runtime.
27
31
  *
28
- * Intended for browsers or frontend runtimes.
32
+ * Intended for backend environments running on Deno.
29
33
  *
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.
34
+ * Typical use cases:
35
+ * - Serverless functions
36
+ * - Edge-like services
36
37
  *
37
- * Authorization and security enforcement are handled
38
- * exclusively by the backend.
38
+ * Supports the use of private API keys.
39
39
  */
40
- | 'client';
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.
51
+ */
52
+ | 'bun'
53
+ /**
54
+ * Browser runtime.
55
+ *
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.
67
+ *
68
+ * Intended for React Native applications (iOS / Android).
69
+ *
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)
75
+ */
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,41 @@ export interface TokenStorage {
71
113
  */
72
114
  export interface BloqueConfig {
73
115
  /**
74
- * Bloque API key.
116
+ * Origin identifier for the SDK.
75
117
  *
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.
118
+ * Used to scope requests and operations
119
+ * to a specific origin within the Bloque platform.
79
120
  */
80
- apiKey: string;
121
+ origin: string;
122
+ /**
123
+ * Platform where the SDK is executed.
124
+ *
125
+ * Determines the runtime environment and its capabilities.
126
+ *
127
+ * - `node` (default): backend runtime (Node.js, Bun, Deno).
128
+ * Supports authentication using private API keys.
129
+ *
130
+ * - `browser`: web browser environment.
131
+ * Does not allow private API keys.
132
+ * Authentication must be performed using JWT.
133
+ *
134
+ * - `react-native`: React Native environment (iOS / Android).
135
+ * Does not allow private API keys.
136
+ * Authentication must be performed using JWT.
137
+ *
138
+ * If not specified, the SDK defaults to `node`.
139
+ */
140
+ platform?: Platform;
141
+ /**
142
+ * Authentication strategy used by the SDK.
143
+ *
144
+ * - `apiKey`: intended for backend platforms (`node`, `bun`, `deno`).
145
+ * - `jwt`: intended for frontend platforms (`browser`, `react-native`).
146
+ *
147
+ * The SDK validates the compatibility between the selected
148
+ * platform and the authentication strategy at runtime.
149
+ */
150
+ auth: AuthStrategy;
81
151
  /**
82
152
  * SDK operation mode.
83
153
  *
@@ -87,15 +157,6 @@ export interface BloqueConfig {
87
157
  * If not specified, the SDK defaults to `production`.
88
158
  */
89
159
  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
160
  /**
100
161
  * JWT token storage strategy.
101
162
  *
@@ -106,6 +167,12 @@ export interface BloqueConfig {
106
167
  * use alternative storage mechanisms.
107
168
  */
108
169
  tokenStorage?: TokenStorage;
170
+ /**
171
+ * Optional access token to be used for authentication.
172
+ *
173
+ * Mainly intended for internal use or advanced scenarios.
174
+ */
175
+ accessToken?: string;
109
176
  }
110
177
  export interface RequestOptions<U = unknown> {
111
178
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
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.22",
4
4
  "description": "Core utilities and types for Bloque SDK.",
5
5
  "type": "module",
6
6
  "keywords": [