@leidenfrost/sdk 0.1.0-alpha.2 → 0.1.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,80 +1,35 @@
1
- leidenfrost-sdk/
2
- ├── .gitignore
3
- ├── .npmignore # Archivos que NO se publican en NPM
4
- ├── README.md # Documentación de instalación y Quickstart
5
- ├── package.json # Configuración con exports ESM y CommonJS
6
- ├── tsup.config.ts # Bundler super rápido (genera /dist)
7
- ├── tsconfig.json # Configuración de TypeScript
8
- │
9
- ├── src/ # Código Fuente
10
- │ ├── index.ts # Entrypoint principal (exporta Leidenfrost, Client, etc.)
11
- │ │
12
- │ ├── core/ # Motor de Infraestructura (Transparente para el usuario)
13
- │ │ ├── HttpClient.ts # Fetch wrapper + auto-retry + firma RS256
14
- │ │ ├── RsaSigner.ts # Firma RS256 usando 'jose' (Caché de CryptoKey)
15
- │ │ ├── Base64.ts # Codificación/Decodificación UTF-8 safe
16
- │ │ └── Errors.ts # Clases de error personalizadas (LeidenfrostError)
17
- │ │
18
- │ ├── config/ # Definición de tipos y defaults
19
- │ │ ├── options.ts # Interfaz LeidenfrostConfig
20
- │ │ └── constants.ts # URLs base, versión, timeouts
21
- │ │
22
- │ ├── modules/ # Servicios de Dominio (La API pública del SDK)
23
- │ │ ├── AuthModule.ts # Customer, Client, Messiah y Admin sessions
24
- │ │ ├── ClientsModule.ts # Gestión de Clientes (Tenants)
25
- │ │ ├── AppsModule.ts # Gestión de Apps por Tenant
26
- │ │ └── ServiceAccountsModule.ts # CRUD de Service Accounts
27
- │ │
28
- │ └── types/ # Tipos TypeScript y Contratos DTO
29
- │ ├── auth.types.ts # Payloads y respuestas de sesión
30
- │ ├── tenant.types.ts # Interfaces de Client, App, SA
31
- │ └── common.types.ts # ApiResponse<T>, Scope types
32
- │
33
- └── dist/ # Carpeta auto-generada tras build (NPM)
34
- ├── index.js # Output CommonJS (CJS)
35
- ├── index.mjs # Output ES Module (ESM)
36
- └── index.d.ts # Definiciones de tipos para autocompletado
37
-
38
- # Estructura de jerarquia
39
- :----------------------------------------------------------------------------------------------------------------------:
40
- | Usuario | Rol de Dominio | Endpoint | Alcance / Permisos |
41
- |:-----------:|:-------------------------------:|:----------------------:|:-------------------------------------------:|
42
- | **Messiah** | `messiah` (SuperAdmin Platform) | `user/messiah/session` | Crear, editar y listar Clientes (Tenants). |
43
- | **Client** | `client` (Tenant/B2B) | `user/client/session/` | Crear, editar y listar Apps. |
44
- | **App** | `app` (Application) | `operational/apps/` | Crear, editar y listar Service-Accounts. |
45
- | **Admin** | `admin` (Personal Operativo) | `user/admin/session/` | Operar recursos asignados a la App. |
46
- | **Customer**| `customer` (Usuario Final/B2C) | `user/costumer/session`| Comprador de mercancia cliente final. |
47
- :----------------------------------------------------------------------------------------------------------------------:
48
-
49
1
  # Ejemplo de Uso del SDK
50
2
 
51
3
  **Etapa 0: Importacion de librerias !**
52
4
  import { Leidenfrost } from "@leidenfrost/sdk";
53
5
 
54
6
  **Etapa 1: Inicializacion del SDK con service account !**
55
- const lf = Leidenfrost.initializeApp({
56
- apiKey: "sa_master_messiah",
57
- keyId: "key_master_e11f32e2",
58
- privateKey: `-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----`,
59
- apiUrl: "http://127.0.0.1:5001/leidenfrost-web/us-central1/app",
60
- });
7
+ import { Leidenfrost } from "@leidenfrost/sdk";
61
8
 
62
- **Etapa 2: Registro (Solo tú como Messiah registras a un nuevo Cliente B2B) !**
63
- const registerRes = await lf.auth.registerClient({
64
- email: "empresa@cliente.com",
65
- password: "Password123!",
66
- name: "Carlos",
67
- last_name: "Gómez",
68
- telephone: "+522221234567"
9
+ const leidenfrost = Leidenfrost.initializeApp({
10
+ type: "example_type",
11
+ clientId: "example_client_id",
12
+ clientEmail: "example.example@example.example",
13
+ privateKeyId: "example_key_id",
14
+ privateKey: "example_private_key",
15
+ scopes: [
16
+ "example:example",
17
+ ]
69
18
  });
70
19
 
71
- **Etapa 2: El Cliente inicia sesión en el CMS !**
72
- const sessionRes = await lf.auth.loginClient("empresa@cliente.com", "Password123!");
73
- if (sessionRes.success) {
74
- const { user, authentication_token, refresh_token } = sessionRes.data;
75
-
76
- // El SDK guarda 'authentication_token' internamente para las siguientes llamadas HTTP
77
- console.log("Bienvenido:", user.name);
78
- console.log("Access Token (8h):", authentication_token);
79
- console.log("Refresh Token (30d):", refresh_token);
80
- }
20
+ export default leidenfrost;
21
+
22
+ **Etapa 2: Registro de usuario !**
23
+
24
+ import leidenfrost from '@/lib/leidenfrost';
25
+
26
+ const requestBody={
27
+ email: authData.email,
28
+ password: authData.password,
29
+ name: authData.name,
30
+ last_name: authData.last_name,
31
+ telephone: authData.phone,
32
+ }
33
+ const response = await leidenfrost.user.postUser(requestBody)
34
+
35
+ **Etapa 2:Obtener informacion de usuario !**
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var m=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var E=(o,e)=>{for(var t in e)m(o,t,{get:e[t],enumerable:!0})},H=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of v(e))!A.call(o,r)&&r!==t&&m(o,r,{get:()=>e[r],enumerable:!(s=U(e,r))||s.enumerable});return o};var q=o=>H(m({},"__esModule",{value:!0}),o);var O={};E(O,{Leidenfrost:()=>f,default:()=>x});module.exports=q(O);var d=require("jose"),l=class{apiKey;keyId;rawPrivateKey;scopes;cachedCryptoKey=null;constructor(e){this.apiKey=e.apiKey,this.keyId=e.keyId,this.rawPrivateKey=this.sanitizePrivateKey(e.privateKey),this.scopes=e.scopes||["*"]}sanitizePrivateKey(e){return e?e.replace(/\\n/g,`
2
- `).trim():""}async getCryptoKey(){if(this.cachedCryptoKey)return this.cachedCryptoKey;if(!this.rawPrivateKey)throw new Error("\u274C [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.");try{return this.cachedCryptoKey=await(0,d.importPKCS8)(this.rawPrivateKey,"RS256"),this.cachedCryptoKey}catch(e){throw new Error(`\u274C [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${e?.message||e}`)}}async generateM2MToken(e){let t=await this.getCryptoKey(),s=Math.floor(Date.now()/1e3),r=e||this.scopes;return await new d.SignJWT({iss:this.apiKey,sub:this.apiKey,scopes:r}).setProtectedHeader({alg:"RS256",kid:this.keyId,typ:"JWT"}).setIssuedAt(s).setExpirationTime(s+3600).sign(t)}clearCache(){this.cachedCryptoKey=null}};var h=class{static encode(e){try{let t=typeof e=="object"&&e!==null?JSON.stringify(e):String(e);if(typeof window<"u"&&typeof window.btoa=="function"){let s=new TextEncoder().encode(t),r="";for(let a=0;a<s.length;a++){let c=s[a];c!==void 0&&(r+=String.fromCharCode(c))}return window.btoa(r)}return Buffer.from(t,"utf-8").toString("base64")}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al codificar payload: ${s}`)}}static decode(e){try{let t="";if(typeof window<"u"&&typeof window.atob=="function"){let s=window.atob(e),r=new Uint8Array(s.length);for(let a=0;a<s.length;a++)r[a]=s.charCodeAt(a);t=new TextDecoder().decode(r)}else t=Buffer.from(e,"base64").toString("utf-8");try{return JSON.parse(t)}catch{return t}}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${s}`)}}};var g=class{apiUrl;signer;userSessionToken=null;constructor(e){this.apiUrl="https://app-fpwuknh76a-uc.a.run.app".replace(/\/$/,"");let t={apiKey:e.clientId,keyId:e.privateKeyId,privateKey:e.privateKey};e.scopes!==void 0&&(t.scopes=e.scopes),this.signer=new l(t)}setUserSessionToken(e){this.userSessionToken=e}getUserSessionToken(){return this.userSessionToken}async request(e,t={}){let{body:s,headers:r,customScopes:a,method:c="GET",...T}=t,b=await this.signer.generateM2MToken(a),p=new Headers;p.set("Content-Type","application/json"),p.set("Accept","application/json"),p.set("Authorization",`Bearer ${b}`),this.userSessionToken&&p.set("x-leidenfrost-session",this.userSessionToken),r&&(r instanceof Headers?r.forEach((n,i)=>p.set(i,n)):Array.isArray(r)?r.forEach(([n,i])=>{n&&i&&p.set(n,i)}):Object.entries(r).forEach(([n,i])=>{i!==void 0&&p.set(n,String(i))}));let u;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let i=s.data?s:{data:h.encode(s)};u=JSON.stringify(i)}else u=String(s);let R=e.startsWith("/")?e:`/${e}`,C=`${this.apiUrl}${R}`,w={...T,method:c,headers:p};u!==void 0&&(w.body=u);let K=new Request(C,w);try{let n=await fetch(K),i=null,k=n.headers.get("content-type");if(k&&k.includes("application/json")?i=await n.json():i=await n.text(),!n.ok){let S=i&&typeof i=="object"?i:{},P={success:!1,status:n.status,message:typeof S.message=="string"?S.message:`Error HTTP ${n.status}: ${n.statusText}`,data:null};return Promise.reject(P)}return i}catch(n){if(n&&typeof n=="object"&&"success"in n)return Promise.reject(n);let i={success:!1,status:500,message:n instanceof Error?n.message:"Error de red o fallo de conexi\xF3n con la API.",data:null};return Promise.reject(i)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}};var y=class{http;constructor(e){this.http=e}async getSession(e){let t=await this.http.get(`/user/session?id=${e}`);return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}async postSession(e,t){let s=await this.http.post("/user/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async patchSession(e){let t=await this.http.patch("/user/session",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}async deleteSession(e){let t=await this.http.delete(`/user/session?refresh_token=${e}`);return t.success&&this.http.setUserSessionToken(null),t}async getUser(e){return await this.http.get(`/user?id=${e}`)}async postUser(e){return await this.http.post("/user",e)}async patchUser(e){return await this.http.patch("/user",e)}async deleteUser(){return await this.http.delete("/user")}};var f=class o{httpClient;user;constructor(e){if(!e.clientId||!e.privateKey)throw new Error("\u274C [Leidenfrost SDK]: La configuraci\xF3n inicial requiere 'clientId/apiKey' y 'privateKey'.");this.httpClient=new g(e),this.user=new y(this.httpClient)}static initializeApp(e){return new o(e)}setUserSessionToken(e){this.httpClient.setUserSessionToken(e)}getUserSessionToken(){return this.httpClient.getUserSessionToken()}},x=f;0&&(module.exports={Leidenfrost});
1
+ "use strict";var S=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var H=Object.prototype.hasOwnProperty;var O=(o,e)=>{for(var t in e)S(o,t,{get:e[t],enumerable:!0})},x=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of P(e))!H.call(o,i)&&i!==t&&S(o,i,{get:()=>e[i],enumerable:!(s=E(e,i))||s.enumerable});return o};var U=o=>x(S({},"__esModule",{value:!0}),o);var q={};O(q,{Leidenfrost:()=>w,default:()=>j});module.exports=U(q);var h=require("jose"),d=class{apiKey;keyId;rawPrivateKey;scopes;cachedCryptoKey=null;constructor(e){this.apiKey=e.apiKey,this.keyId=e.keyId,this.rawPrivateKey=this.sanitizePrivateKey(e.privateKey),this.scopes=e.scopes||["*"]}sanitizePrivateKey(e){return e?e.replace(/\\n/g,`
2
+ `).trim():""}async getCryptoKey(){if(this.cachedCryptoKey)return this.cachedCryptoKey;if(!this.rawPrivateKey)throw new Error("\u274C [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.");try{return this.cachedCryptoKey=await(0,h.importPKCS8)(this.rawPrivateKey,"RS256"),this.cachedCryptoKey}catch(e){throw new Error(`\u274C [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${e?.message||e}`)}}async generateM2MToken(e){let t=await this.getCryptoKey(),s=Math.floor(Date.now()/1e3),i=e||this.scopes;return await new h.SignJWT({iss:this.apiKey,sub:this.apiKey,scopes:i}).setProtectedHeader({alg:"RS256",kid:this.keyId,typ:"JWT"}).setIssuedAt(s).setExpirationTime(s+3600).sign(t)}clearCache(){this.cachedCryptoKey=null}};var f=class{static encode(e){try{let t=typeof e=="object"&&e!==null?JSON.stringify(e):String(e);if(typeof window<"u"&&typeof window.btoa=="function"){let s=new TextEncoder().encode(t),i="";for(let a=0;a<s.length;a++){let c=s[a];c!==void 0&&(i+=String.fromCharCode(c))}return window.btoa(i)}return Buffer.from(t,"utf-8").toString("base64")}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al codificar payload: ${s}`)}}static decode(e){try{let t="";if(typeof window<"u"&&typeof window.atob=="function"){let s=window.atob(e),i=new Uint8Array(s.length);for(let a=0;a<s.length;a++)i[a]=s.charCodeAt(a);t=new TextDecoder().decode(i)}else t=Buffer.from(e,"base64").toString("utf-8");try{return JSON.parse(t)}catch{return t}}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${s}`)}}};var y=class{apiUrl;signer;session=null;STORAGE_KEY="leidenfrost_session";constructor(e){this.apiUrl="https://app-fpwuknh76a-uc.a.run.app".replace(/\/$/,"");let t={apiKey:e.clientId,keyId:e.privateKeyId,privateKey:e.privateKey};if(e.scopes!==void 0&&(t.scopes=e.scopes),this.signer=new d(t),typeof window<"u"&&window.localStorage){let s=localStorage.getItem(this.STORAGE_KEY);if(s)try{this.session=JSON.parse(s)}catch{this.session=null}}}setSession(e){this.session=e,typeof window<"u"&&window.localStorage&&localStorage.setItem(this.STORAGE_KEY,JSON.stringify(e))}getSession(){return this.session}removeSession(){this.session=null,typeof window<"u"&&window.localStorage&&localStorage.removeItem(this.STORAGE_KEY)}async request(e,t={}){let{body:s,headers:i,customScopes:a,method:c="GET",...T}=t,k=await this.signer.generateM2MToken(a),p=new Headers;p.set("Content-Type","application/json"),p.set("Accept","application/json"),p.set("Authorization",`Bearer ${k}`),this.session?.authentication_token&&p.set("x-leidenfrost-session",this.session.authentication_token),i&&(i instanceof Headers?i.forEach((n,r)=>p.set(r,n)):Array.isArray(i)?i.forEach(([n,r])=>{n&&r&&p.set(n,r)}):Object.entries(i).forEach(([n,r])=>{r!==void 0&&p.set(n,String(r))}));let u;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let r=s.data?s:{data:f.encode(s)};u=JSON.stringify(r)}else u=String(s);let K=e.startsWith("/")?e:`/${e}`,C=`${this.apiUrl}${K}`,R={...T,method:c,headers:p};u!==void 0&&(R.body=u);let v=new Request(C,R);try{let n=await fetch(v),r=null,b=n.headers.get("content-type");if(b&&b.includes("application/json")?r=await n.json():r=await n.text(),n.status===401){this.removeSession(),typeof window<"u"&&(window.location.href="/");let l={success:!1,status:n.status,message:"Your session has expired",data:null};return Promise.reject(l)}if(!n.ok){let l=r&&typeof r=="object"?r:{},A={success:!1,status:n.status,message:typeof l.message=="string"?l.message:`Error HTTP ${n.status}: ${n.statusText}`,data:null};return Promise.reject(A)}return r}catch(n){if(n&&typeof n=="object"&&"success"in n)return Promise.reject(n);let r={success:!1,status:500,message:n instanceof Error?n.message:"Error de red o fallo de conexi\xF3n con la API.",data:null};return Promise.reject(r)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}};var g=class{http;constructor(e){this.http=e}async getUser(e){return await this.http.get(`/user?id=${e}`)}async postUser(e){return await this.http.post("/user",e)}async patchUser(e){return await this.http.patch("/user",e)}async deleteUser(){return await this.http.delete("/user")}};var m=class{http;constructor(e){this.http=e}async getSession(e){let t=await this.http.get(`/user/session?id=${e}`);return t.success&&t.data?.authentication_token&&this.http.setSession(t.data),t}async postSession(e,t){let s=await this.http.post("/user/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setSession(s.data),s}async patchSession(e){let t=await this.http.patch("/user/session",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setSession(t.data),t}async deleteSession(e){let t=await this.http.delete(`/user/session?refresh_token=${e}`);return t.success&&this.http.removeSession(),t}};var w=class o{httpClient;user;session;constructor(e){if(!e.clientId||!e.privateKey)throw new Error("\u274C [Leidenfrost SDK]: La configuraci\xF3n inicial requiere 'clientId/apiKey' y 'privateKey'.");this.httpClient=new y(e),this.user=new g(this.httpClient),this.session=new m(this.httpClient)}static initializeApp(e){return new o(e)}},j=w;0&&(module.exports={Leidenfrost});
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/RsaSigner.ts","../src/core/Base64.ts","../src/core/HttpClient.ts","../src/modules/UserModule.ts"],"sourcesContent":["import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig } from \"./core/HttpClient.js\";\nimport { UserModule } from \"./modules/UserModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\n\nexport type {\n User,\n Session,\n} from \"./modules/UserModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public user: UserModule;\n\n constructor(config: HttpClientConfig) {\n if (!config.clientId || !config.privateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La configuración inicial requiere 'clientId/apiKey' y 'privateKey'.\"\n );\n }\n\n this.httpClient = new HttpClient(config);\n this.user = new UserModule(this.httpClient);\n }\n\n public static initializeApp(config: HttpClientConfig): Leidenfrost {\n return new Leidenfrost(config);\n }\n\n public setUserSessionToken(token: string | null): void {\n this.httpClient.setUserSessionToken(token);\n }\n\n public getUserSessionToken(): string | null {\n return this.httpClient.getUserSessionToken();\n }\n}\n\nexport default Leidenfrost;","import { SignJWT, importPKCS8 } from \"jose\";\n\nexport interface RsaSignerOptions {\n apiKey: string;\n keyId: string;\n privateKey: string;\n scopes?: string[] | undefined;\n}\n\nexport class RsaSigner {\n private apiKey: string;\n private keyId: string;\n private rawPrivateKey: string;\n private scopes: string[];\n private cachedCryptoKey: CryptoKey | null = null;\n\n constructor(options: RsaSignerOptions) {\n this.apiKey = options.apiKey;\n this.keyId = options.keyId;\n this.rawPrivateKey = this.sanitizePrivateKey(options.privateKey);\n this.scopes = options.scopes || [\"*\"];\n }\n\n /**\n * Reemplaza saltos de línea escapados por saltos de línea reales PEM\n */\n private sanitizePrivateKey(key: string): string {\n if (!key) return \"\";\n return key.replace(/\\\\n/g, \"\\n\").trim();\n }\n\n /**\n * Obtiene e importa la llave privada PKCS#8 a WebCrypto, utilizando caché en memoria\n */\n private async getCryptoKey(): Promise<CryptoKey> {\n if (this.cachedCryptoKey) {\n return this.cachedCryptoKey;\n }\n\n if (!this.rawPrivateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.\"\n );\n }\n\n try {\n this.cachedCryptoKey = (await importPKCS8(\n this.rawPrivateKey,\n \"RS256\"\n )) as CryptoKey;\n return this.cachedCryptoKey;\n } catch (error: any) {\n throw new Error(\n `❌ [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${error?.message || error}`\n );\n }\n }\n\n /**\n * Genera un JWT de Service Account firmado con RS256 (válido por 1 hora)\n */\n public async generateM2MToken(customScopes?: string[]): Promise<string> {\n const cryptoKey = await this.getCryptoKey();\n const now = Math.floor(Date.now() / 1000);\n const targetScopes = customScopes || this.scopes;\n\n return await new SignJWT({\n iss: this.apiKey,\n sub: this.apiKey,\n scopes: targetScopes,\n })\n .setProtectedHeader({ alg: \"RS256\", kid: this.keyId, typ: \"JWT\" })\n .setIssuedAt(now)\n .setExpirationTime(now + 3600)\n .sign(cryptoKey);\n }\n\n /**\n * Limpia la caché de la llave procesada\n */\n public clearCache(): void {\n this.cachedCryptoKey = null;\n }\n}\n\n","export class Base64 {\n /**\n * Codifica un objeto o cadena en Base64 con soporte UTF-8\n */\n public static encode(data: unknown): string {\n try {\n const jsonString =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data)\n : String(data);\n\n if (typeof window !== \"undefined\" && typeof window.btoa === \"function\") {\n const utf8Bytes = new TextEncoder().encode(jsonString);\n let binaryString = \"\";\n for (let i = 0; i < utf8Bytes.length; i++) {\n const byte = utf8Bytes[i];\n if (byte !== undefined) {\n binaryString += String.fromCharCode(byte);\n }\n }\n return window.btoa(binaryString);\n }\n\n // Entorno Node.js\n return Buffer.from(jsonString, \"utf-8\").toString(\"base64\");\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al codificar payload: ${msg}`);\n }\n }\n\n /**\n * Decodifica una cadena Base64\n */\n public static decode<T = unknown>(base64String: string): T {\n try {\n let jsonString = \"\";\n\n if (typeof window !== \"undefined\" && typeof window.atob === \"function\") {\n const binaryString = window.atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n jsonString = new TextDecoder().decode(bytes);\n } else {\n jsonString = Buffer.from(base64String, \"base64\").toString(\"utf-8\");\n }\n\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${msg}`);\n }\n }\n}","import { RsaSigner } from \"./RsaSigner.js\";\nimport type { RsaSignerOptions } from \"./RsaSigner.js\";\nimport { Base64 } from \"./Base64.js\";\n\nexport interface HttpRequestOptions extends Omit<RequestInit, \"body\"> {\n body?: unknown;\n customScopes?: string[];\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data: T;\n status?: number;\n}\n\nexport interface HttpClientConfig {\n type: string;\n clientId: string;\n clientEmail: string;\n privateKeyId: string;\n privateKey: string;\n scopes?: string[];\n}\n\n\nexport class HttpClient {\n private apiUrl: string;\n private signer: RsaSigner;\n private userSessionToken: string | null = null;\n\n constructor(config: HttpClientConfig) {\n this.apiUrl = \"https://app-fpwuknh76a-uc.a.run.app\".replace(/\\/$/, \"\");\n\n const signerOpts: RsaSignerOptions = {\n apiKey: config.clientId,\n keyId: config.privateKeyId,\n privateKey: config.privateKey,\n };\n\n if (config.scopes !== undefined) {\n signerOpts.scopes = config.scopes;\n }\n\n this.signer = new RsaSigner(signerOpts);\n }\n\n public setUserSessionToken(token: string | null): void {\n this.userSessionToken = token;\n }\n\n public getUserSessionToken(): string | null {\n return this.userSessionToken;\n }\n\n public async request<T = unknown>(\n endpoint: string,\n options: HttpRequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { body, headers, customScopes, method = \"GET\", ...restOptions } = options;\n\n const m2mToken = await this.signer.generateM2MToken(customScopes);\n\n // 1. Cabeceras con objeto Headers nativo\n const requestHeaders = new Headers();\n requestHeaders.set(\"Content-Type\", \"application/json\");\n requestHeaders.set(\"Accept\", \"application/json\");\n requestHeaders.set(\"Authorization\", `Bearer ${m2mToken}`);\n\n if (this.userSessionToken) {\n requestHeaders.set(\"x-leidenfrost-session\", this.userSessionToken);\n }\n\n if (headers) {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => requestHeaders.set(key, value));\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n if (key && value) requestHeaders.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) requestHeaders.set(key, String(value));\n });\n }\n }\n\n // 2. Procesamiento del Body\n let requestBody: string | undefined = undefined;\n if (body !== undefined && body !== null) {\n if (typeof body === \"object\" && !(body instanceof FormData)) {\n const bodyRecord = body as Record<string, unknown>;\n const payloadToEncode = bodyRecord[\"data\"] ? body : { data: Base64.encode(body) };\n requestBody = JSON.stringify(payloadToEncode);\n } else {\n requestBody = String(body);\n }\n }\n\n const cleanEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n const fullUrl = `${this.apiUrl}${cleanEndpoint}`;\n\n // 3. Objeto de opciones flexible\n const requestInitOptions: Record<string, unknown> = {\n ...(restOptions as Record<string, unknown>),\n method: method as string,\n headers: requestHeaders,\n };\n\n if (requestBody !== undefined) {\n requestInitOptions[\"body\"] = requestBody;\n }\n\n // 4. Instancia de Request limpia\n const requestInstance = new Request(fullUrl, requestInitOptions as unknown as RequestInit);\n\n try {\n const response = await fetch(requestInstance);\n\n let responseData: unknown = null;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType && contentType.includes(\"application/json\")) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (!response.ok) {\n const errorRecord = (responseData && typeof responseData === \"object\") ? (responseData as Record<string, unknown>) : {};\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: typeof errorRecord[\"message\"] === \"string\" ? errorRecord[\"message\"] : `Error HTTP ${response.status}: ${response.statusText}`,\n data: null,\n };\n return Promise.reject(errorResult);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error: unknown) {\n if (error && typeof error === \"object\" && \"success\" in error) {\n return Promise.reject(error);\n }\n\n const networkError: ApiResponse<null> = {\n success: false,\n status: 500,\n message: error instanceof Error ? error.message : \"Error de red o fallo de conexión con la API.\",\n data: null,\n };\n return Promise.reject(networkError);\n }\n }\n\n public get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n public post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n public put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n public patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PATCH\", body });\n }\n\n public delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface User {\n id?: string;\n tenant_id?:string;\n email: string;\n password?: string;\n name: string;\n last_name: string;\n telephone?: string;\n role?: \"messiah\" | \"client\" | \"admin\" | \"customer\";\n membership?: {\n name: string;\n level: number;\n points: number;\n coupons: unknown[];\n };\n enabled?: boolean;\n created_at?: unknown;\n update_at?: unknown;\n}\n\nexport interface Session {\n user: User;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport class UserModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n /**\n * Module: Session\n * Ruta: /user/session\n */\n public async getSession(id:string): Promise<ApiResponse<Session>> {\n const response = await this.http.get<Session>(`/user/session?id=${id}`);\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async postSession(email: string, password: string): Promise<ApiResponse<Session>> {\n const response = await this.http.post<Session>(\"/user/session\", { email, password });\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async patchSession(refreshToken: string): Promise<ApiResponse<Session>> {\n const response = await this.http.patch<Session>(\"/user/session\", { refresh_token: refreshToken });\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async deleteSession(refreshToken: string): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(`/user/session?refresh_token=${refreshToken}`);\n if (response.success) {\n this.http.setUserSessionToken(null);\n }\n return response;\n }\n\n /**\n * Module: USER\n * Ruta: /user\n */\n public async getUser(id:string): Promise<ApiResponse<User>> {\n const response = await this.http.get<User>(`/user?id=${id}`);\n return response;\n }\n public async postUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.post<User>(\"/user\", data);\n return response;\n }\n public async patchUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.patch<User>(\"/user\", data);\n return response;\n }\n public async deleteUser(): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(\"/user\");\n return response;\n }\n}"],"mappings":"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","names":["index_exports","__export","Leidenfrost","index_default","__toCommonJS","import_jose","RsaSigner","options","key","error","customScopes","cryptoKey","now","targetScopes","Base64","data","jsonString","utf8Bytes","binaryString","i","byte","error","msg","base64String","bytes","HttpClient","config","signerOpts","RsaSigner","token","endpoint","options","body","headers","customScopes","method","restOptions","m2mToken","requestHeaders","value","key","requestBody","payloadToEncode","Base64","cleanEndpoint","fullUrl","requestInitOptions","requestInstance","response","responseData","contentType","errorRecord","errorResult","error","networkError","UserModule","httpClient","id","response","email","password","refreshToken","data","Leidenfrost","_Leidenfrost","config","HttpClient","UserModule","token","index_default"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/RsaSigner.ts","../src/core/Base64.ts","../src/core/HttpClient.ts","../src/modules/UserModule.ts","../src/modules/SessionModule.ts"],"sourcesContent":["import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig } from \"./core/HttpClient.js\";\nimport { UserModule } from \"./modules/UserModule.js\";\nimport { SessionModule } from \"./modules/SessionModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\n\nexport type {\n User,\n} from \"./modules/UserModule.js\";\n\nexport type {\n Session,\n} from \"./modules/SessionModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public user: UserModule;\n public session : SessionModule;\n\n constructor(config: HttpClientConfig) {\n if (!config.clientId || !config.privateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La configuración inicial requiere 'clientId/apiKey' y 'privateKey'.\"\n );\n }\n\n this.httpClient = new HttpClient(config);\n this.user = new UserModule(this.httpClient);\n this.session = new SessionModule(this.httpClient);\n }\n\n public static initializeApp(config: HttpClientConfig): Leidenfrost {\n return new Leidenfrost(config);\n }\n}\n\nexport default Leidenfrost;","import { SignJWT, importPKCS8 } from \"jose\";\n\nexport interface RsaSignerOptions {\n apiKey: string;\n keyId: string;\n privateKey: string;\n scopes?: string[] | undefined;\n}\n\nexport class RsaSigner {\n private apiKey: string;\n private keyId: string;\n private rawPrivateKey: string;\n private scopes: string[];\n private cachedCryptoKey: CryptoKey | null = null;\n\n constructor(options: RsaSignerOptions) {\n this.apiKey = options.apiKey;\n this.keyId = options.keyId;\n this.rawPrivateKey = this.sanitizePrivateKey(options.privateKey);\n this.scopes = options.scopes || [\"*\"];\n }\n\n /**\n * Reemplaza saltos de línea escapados por saltos de línea reales PEM\n */\n private sanitizePrivateKey(key: string): string {\n if (!key) return \"\";\n return key.replace(/\\\\n/g, \"\\n\").trim();\n }\n\n /**\n * Obtiene e importa la llave privada PKCS#8 a WebCrypto, utilizando caché en memoria\n */\n private async getCryptoKey(): Promise<CryptoKey> {\n if (this.cachedCryptoKey) {\n return this.cachedCryptoKey;\n }\n\n if (!this.rawPrivateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.\"\n );\n }\n\n try {\n this.cachedCryptoKey = (await importPKCS8(\n this.rawPrivateKey,\n \"RS256\"\n )) as CryptoKey;\n return this.cachedCryptoKey;\n } catch (error: any) {\n throw new Error(\n `❌ [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${error?.message || error}`\n );\n }\n }\n\n /**\n * Genera un JWT de Service Account firmado con RS256 (válido por 1 hora)\n */\n public async generateM2MToken(customScopes?: string[]): Promise<string> {\n const cryptoKey = await this.getCryptoKey();\n const now = Math.floor(Date.now() / 1000);\n const targetScopes = customScopes || this.scopes;\n\n return await new SignJWT({\n iss: this.apiKey,\n sub: this.apiKey,\n scopes: targetScopes,\n })\n .setProtectedHeader({ alg: \"RS256\", kid: this.keyId, typ: \"JWT\" })\n .setIssuedAt(now)\n .setExpirationTime(now + 3600)\n .sign(cryptoKey);\n }\n\n /**\n * Limpia la caché de la llave procesada\n */\n public clearCache(): void {\n this.cachedCryptoKey = null;\n }\n}\n\n","export class Base64 {\n /**\n * Codifica un objeto o cadena en Base64 con soporte UTF-8\n */\n public static encode(data: unknown): string {\n try {\n const jsonString =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data)\n : String(data);\n\n if (typeof window !== \"undefined\" && typeof window.btoa === \"function\") {\n const utf8Bytes = new TextEncoder().encode(jsonString);\n let binaryString = \"\";\n for (let i = 0; i < utf8Bytes.length; i++) {\n const byte = utf8Bytes[i];\n if (byte !== undefined) {\n binaryString += String.fromCharCode(byte);\n }\n }\n return window.btoa(binaryString);\n }\n\n // Entorno Node.js\n return Buffer.from(jsonString, \"utf-8\").toString(\"base64\");\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al codificar payload: ${msg}`);\n }\n }\n\n /**\n * Decodifica una cadena Base64\n */\n public static decode<T = unknown>(base64String: string): T {\n try {\n let jsonString = \"\";\n\n if (typeof window !== \"undefined\" && typeof window.atob === \"function\") {\n const binaryString = window.atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n jsonString = new TextDecoder().decode(bytes);\n } else {\n jsonString = Buffer.from(base64String, \"base64\").toString(\"utf-8\");\n }\n\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${msg}`);\n }\n }\n}","import { RsaSigner } from \"./RsaSigner.js\";\nimport type { RsaSignerOptions } from \"./RsaSigner.js\";\nimport { Base64 } from \"./Base64.js\";\nimport type { Session } from \"../modules/SessionModule.js\";\n\nexport interface HttpRequestOptions extends Omit<RequestInit, \"body\"> {\n body?: unknown;\n customScopes?: string[];\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data: T;\n status?: number;\n}\n\nexport interface HttpClientConfig {\n type: string;\n clientId: string;\n clientEmail: string;\n privateKeyId: string;\n privateKey: string;\n scopes?: string[];\n}\n\n\nexport class HttpClient {\n private apiUrl: string;\n private signer: RsaSigner;\n\n private session: Session | null = null;\n private readonly STORAGE_KEY = 'leidenfrost_session';\n\n constructor(config: HttpClientConfig) {\n this.apiUrl = \"https://app-fpwuknh76a-uc.a.run.app\".replace(/\\/$/, \"\");\n\n const signerOpts: RsaSignerOptions = {\n apiKey: config.clientId,\n keyId: config.privateKeyId,\n privateKey: config.privateKey,\n };\n\n if (config.scopes !== undefined) {\n signerOpts.scopes = config.scopes;\n }\n\n this.signer = new RsaSigner(signerOpts);\n \n if (typeof window !== 'undefined' && window.localStorage) {\n const saved = localStorage.getItem(this.STORAGE_KEY);\n if (saved) {\n try {\n this.session = JSON.parse(saved);\n } catch {\n this.session = null;\n }\n }\n }\n }\n\n public setSession(sessionData: Session): void {\n this.session = sessionData;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(sessionData));\n }\n }\n\n public getSession(): Session | null {\n return this.session;\n }\n\n public removeSession(): void {\n this.session = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem(this.STORAGE_KEY);\n }\n }\n\n public async request<T = unknown>(\n endpoint: string,\n options: HttpRequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { body, headers, customScopes, method = \"GET\", ...restOptions } = options;\n\n const m2mToken = await this.signer.generateM2MToken(customScopes);\n\n // 1. Cabeceras con objeto Headers nativo\n const requestHeaders = new Headers();\n requestHeaders.set(\"Content-Type\", \"application/json\");\n requestHeaders.set(\"Accept\", \"application/json\");\n requestHeaders.set(\"Authorization\", `Bearer ${m2mToken}`);\n\n if (this.session?.authentication_token) {\n requestHeaders.set(\"x-leidenfrost-session\", this.session.authentication_token);\n }\n\n if (headers) {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => requestHeaders.set(key, value));\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n if (key && value) requestHeaders.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) requestHeaders.set(key, String(value));\n });\n }\n }\n\n // 2. Procesamiento del Body\n let requestBody: string | undefined = undefined;\n if (body !== undefined && body !== null) {\n if (typeof body === \"object\" && !(body instanceof FormData)) {\n const bodyRecord = body as Record<string, unknown>;\n const payloadToEncode = bodyRecord[\"data\"] ? body : { data: Base64.encode(body) };\n requestBody = JSON.stringify(payloadToEncode);\n } else {\n requestBody = String(body);\n }\n }\n\n const cleanEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n const fullUrl = `${this.apiUrl}${cleanEndpoint}`;\n\n // 3. Objeto de opciones flexible\n const requestInitOptions: Record<string, unknown> = {\n ...(restOptions as Record<string, unknown>),\n method: method as string,\n headers: requestHeaders,\n };\n\n if (requestBody !== undefined) {\n requestInitOptions[\"body\"] = requestBody;\n }\n\n // 4. Instancia de Request limpia\n const requestInstance = new Request(fullUrl, requestInitOptions as unknown as RequestInit);\n\n try {\n const response = await fetch(requestInstance);\n\n let responseData: unknown = null;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType && contentType.includes(\"application/json\")) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (response.status === 401) {\n this.removeSession();\n \n // Opcional: Redirigir directamente al login si estás en el cliente\n if (typeof window !== 'undefined') {\n window.location.href = '/';\n }\n\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: \"Your session has expired\",\n data: null,\n };\n\n return Promise.reject(errorResult);\n }\n\n if (!response.ok) {\n const errorRecord = (responseData && typeof responseData === \"object\") ? (responseData as Record<string, unknown>) : {};\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: typeof errorRecord[\"message\"] === \"string\" ? errorRecord[\"message\"] : `Error HTTP ${response.status}: ${response.statusText}`,\n data: null,\n };\n return Promise.reject(errorResult);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error: unknown) {\n if (error && typeof error === \"object\" && \"success\" in error) {\n return Promise.reject(error);\n }\n\n const networkError: ApiResponse<null> = {\n success: false,\n status: 500,\n message: error instanceof Error ? error.message : \"Error de red o fallo de conexión con la API.\",\n data: null,\n };\n return Promise.reject(networkError);\n }\n }\n\n public get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n public post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n public put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n public patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PATCH\", body });\n }\n\n public delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface User {\n id?: string;\n tenant_id?:string;\n email: string;\n password?: string;\n name: string;\n last_name: string;\n telephone?: string;\n role?: \"messiah\" | \"client\" | \"admin\" | \"customer\";\n membership?: {\n name: string;\n level: number;\n points: number;\n coupons: unknown[];\n };\n enabled?: boolean;\n created_at?: unknown;\n update_at?: unknown;\n}\n\nexport class UserModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n /**\n * Module: USER\n * Ruta: /user\n */\n public async getUser(id:string): Promise<ApiResponse<User>> {\n const response = await this.http.get<User>(`/user?id=${id}`);\n return response;\n }\n public async postUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.post<User>(\"/user\", data);\n return response;\n }\n public async patchUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.patch<User>(\"/user\", data);\n return response;\n }\n public async deleteUser(): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(\"/user\");\n return response;\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\nimport type { User } from \"./UserModule.js\";\n\nexport interface Session {\n user: User;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport class SessionModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n /**\n * Module: Session\n * Ruta: /user/session\n */\n public async getSession(id:string): Promise<ApiResponse<Session>> {\n const response = await this.http.get<Session>(`/user/session?id=${id}`);\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async postSession(email: string, password: string): Promise<ApiResponse<Session>> {\n const response = await this.http.post<Session>(\"/user/session\", { email, password });\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async patchSession(refreshToken: string): Promise<ApiResponse<Session>> {\n const response = await this.http.patch<Session>(\"/user/session\", { refresh_token: refreshToken });\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async deleteSession(refreshToken: string): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(`/user/session?refresh_token=${refreshToken}`);\n if (response.success) {\n this.http.removeSession();\n }\n return response;\n }\n}"],"mappings":"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","names":["index_exports","__export","Leidenfrost","index_default","__toCommonJS","import_jose","RsaSigner","options","key","error","customScopes","cryptoKey","now","targetScopes","Base64","data","jsonString","utf8Bytes","binaryString","i","byte","error","msg","base64String","bytes","HttpClient","config","signerOpts","RsaSigner","saved","sessionData","endpoint","options","body","headers","customScopes","method","restOptions","m2mToken","requestHeaders","value","key","requestBody","payloadToEncode","Base64","cleanEndpoint","fullUrl","requestInitOptions","requestInstance","response","responseData","contentType","errorResult","errorRecord","error","networkError","UserModule","httpClient","id","data","SessionModule","httpClient","id","response","email","password","refreshToken","Leidenfrost","_Leidenfrost","config","HttpClient","UserModule","SessionModule","index_default"]}
package/dist/index.d.cts CHANGED
@@ -1,36 +1,3 @@
1
- interface HttpRequestOptions extends Omit<RequestInit, "body"> {
2
- body?: unknown;
3
- customScopes?: string[];
4
- }
5
- interface ApiResponse<T = unknown> {
6
- success: boolean;
7
- message?: string;
8
- data: T;
9
- status?: number;
10
- }
11
- interface HttpClientConfig {
12
- type: string;
13
- clientId: string;
14
- clientEmail: string;
15
- privateKeyId: string;
16
- privateKey: string;
17
- scopes?: string[];
18
- }
19
- declare class HttpClient {
20
- private apiUrl;
21
- private signer;
22
- private userSessionToken;
23
- constructor(config: HttpClientConfig);
24
- setUserSessionToken(token: string | null): void;
25
- getUserSessionToken(): string | null;
26
- request<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
27
- get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
28
- post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
29
- put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
30
- patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
31
- delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
32
- }
33
-
34
1
  interface User {
35
2
  id?: string;
36
3
  tenant_id?: string;
@@ -50,12 +17,25 @@ interface User {
50
17
  created_at?: unknown;
51
18
  update_at?: unknown;
52
19
  }
20
+ declare class UserModule {
21
+ private http;
22
+ constructor(httpClient: HttpClient);
23
+ /**
24
+ * Module: USER
25
+ * Ruta: /user
26
+ */
27
+ getUser(id: string): Promise<ApiResponse<User>>;
28
+ postUser(data: User): Promise<ApiResponse<User>>;
29
+ patchUser(data: User): Promise<ApiResponse<User>>;
30
+ deleteUser(): Promise<ApiResponse<null>>;
31
+ }
32
+
53
33
  interface Session {
54
34
  user: User;
55
35
  authentication_token: string;
56
36
  refresh_token: string;
57
37
  }
58
- declare class UserModule {
38
+ declare class SessionModule {
59
39
  private http;
60
40
  constructor(httpClient: HttpClient);
61
41
  /**
@@ -66,23 +46,49 @@ declare class UserModule {
66
46
  postSession(email: string, password: string): Promise<ApiResponse<Session>>;
67
47
  patchSession(refreshToken: string): Promise<ApiResponse<Session>>;
68
48
  deleteSession(refreshToken: string): Promise<ApiResponse<null>>;
69
- /**
70
- * Module: USER
71
- * Ruta: /user
72
- */
73
- getUser(id: string): Promise<ApiResponse<User>>;
74
- postUser(data: User): Promise<ApiResponse<User>>;
75
- patchUser(data: User): Promise<ApiResponse<User>>;
76
- deleteUser(): Promise<ApiResponse<null>>;
49
+ }
50
+
51
+ interface HttpRequestOptions extends Omit<RequestInit, "body"> {
52
+ body?: unknown;
53
+ customScopes?: string[];
54
+ }
55
+ interface ApiResponse<T = unknown> {
56
+ success: boolean;
57
+ message?: string;
58
+ data: T;
59
+ status?: number;
60
+ }
61
+ interface HttpClientConfig {
62
+ type: string;
63
+ clientId: string;
64
+ clientEmail: string;
65
+ privateKeyId: string;
66
+ privateKey: string;
67
+ scopes?: string[];
68
+ }
69
+ declare class HttpClient {
70
+ private apiUrl;
71
+ private signer;
72
+ private session;
73
+ private readonly STORAGE_KEY;
74
+ constructor(config: HttpClientConfig);
75
+ setSession(sessionData: Session): void;
76
+ getSession(): Session | null;
77
+ removeSession(): void;
78
+ request<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
79
+ get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
80
+ post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
81
+ put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
82
+ patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
83
+ delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
77
84
  }
78
85
 
79
86
  declare class Leidenfrost {
80
87
  private httpClient;
81
88
  user: UserModule;
89
+ session: SessionModule;
82
90
  constructor(config: HttpClientConfig);
83
91
  static initializeApp(config: HttpClientConfig): Leidenfrost;
84
- setUserSessionToken(token: string | null): void;
85
- getUserSessionToken(): string | null;
86
92
  }
87
93
 
88
94
  export { type ApiResponse, type HttpClientConfig, Leidenfrost, type Session, type User, Leidenfrost as default };
package/dist/index.d.ts CHANGED
@@ -1,36 +1,3 @@
1
- interface HttpRequestOptions extends Omit<RequestInit, "body"> {
2
- body?: unknown;
3
- customScopes?: string[];
4
- }
5
- interface ApiResponse<T = unknown> {
6
- success: boolean;
7
- message?: string;
8
- data: T;
9
- status?: number;
10
- }
11
- interface HttpClientConfig {
12
- type: string;
13
- clientId: string;
14
- clientEmail: string;
15
- privateKeyId: string;
16
- privateKey: string;
17
- scopes?: string[];
18
- }
19
- declare class HttpClient {
20
- private apiUrl;
21
- private signer;
22
- private userSessionToken;
23
- constructor(config: HttpClientConfig);
24
- setUserSessionToken(token: string | null): void;
25
- getUserSessionToken(): string | null;
26
- request<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
27
- get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
28
- post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
29
- put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
30
- patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
31
- delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
32
- }
33
-
34
1
  interface User {
35
2
  id?: string;
36
3
  tenant_id?: string;
@@ -50,12 +17,25 @@ interface User {
50
17
  created_at?: unknown;
51
18
  update_at?: unknown;
52
19
  }
20
+ declare class UserModule {
21
+ private http;
22
+ constructor(httpClient: HttpClient);
23
+ /**
24
+ * Module: USER
25
+ * Ruta: /user
26
+ */
27
+ getUser(id: string): Promise<ApiResponse<User>>;
28
+ postUser(data: User): Promise<ApiResponse<User>>;
29
+ patchUser(data: User): Promise<ApiResponse<User>>;
30
+ deleteUser(): Promise<ApiResponse<null>>;
31
+ }
32
+
53
33
  interface Session {
54
34
  user: User;
55
35
  authentication_token: string;
56
36
  refresh_token: string;
57
37
  }
58
- declare class UserModule {
38
+ declare class SessionModule {
59
39
  private http;
60
40
  constructor(httpClient: HttpClient);
61
41
  /**
@@ -66,23 +46,49 @@ declare class UserModule {
66
46
  postSession(email: string, password: string): Promise<ApiResponse<Session>>;
67
47
  patchSession(refreshToken: string): Promise<ApiResponse<Session>>;
68
48
  deleteSession(refreshToken: string): Promise<ApiResponse<null>>;
69
- /**
70
- * Module: USER
71
- * Ruta: /user
72
- */
73
- getUser(id: string): Promise<ApiResponse<User>>;
74
- postUser(data: User): Promise<ApiResponse<User>>;
75
- patchUser(data: User): Promise<ApiResponse<User>>;
76
- deleteUser(): Promise<ApiResponse<null>>;
49
+ }
50
+
51
+ interface HttpRequestOptions extends Omit<RequestInit, "body"> {
52
+ body?: unknown;
53
+ customScopes?: string[];
54
+ }
55
+ interface ApiResponse<T = unknown> {
56
+ success: boolean;
57
+ message?: string;
58
+ data: T;
59
+ status?: number;
60
+ }
61
+ interface HttpClientConfig {
62
+ type: string;
63
+ clientId: string;
64
+ clientEmail: string;
65
+ privateKeyId: string;
66
+ privateKey: string;
67
+ scopes?: string[];
68
+ }
69
+ declare class HttpClient {
70
+ private apiUrl;
71
+ private signer;
72
+ private session;
73
+ private readonly STORAGE_KEY;
74
+ constructor(config: HttpClientConfig);
75
+ setSession(sessionData: Session): void;
76
+ getSession(): Session | null;
77
+ removeSession(): void;
78
+ request<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
79
+ get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
80
+ post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
81
+ put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
82
+ patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
83
+ delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
77
84
  }
78
85
 
79
86
  declare class Leidenfrost {
80
87
  private httpClient;
81
88
  user: UserModule;
89
+ session: SessionModule;
82
90
  constructor(config: HttpClientConfig);
83
91
  static initializeApp(config: HttpClientConfig): Leidenfrost;
84
- setUserSessionToken(token: string | null): void;
85
- getUserSessionToken(): string | null;
86
92
  }
87
93
 
88
94
  export { type ApiResponse, type HttpClientConfig, Leidenfrost, type Session, type User, Leidenfrost as default };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import{SignJWT as K,importPKCS8 as P}from"jose";var l=class{apiKey;keyId;rawPrivateKey;scopes;cachedCryptoKey=null;constructor(e){this.apiKey=e.apiKey,this.keyId=e.keyId,this.rawPrivateKey=this.sanitizePrivateKey(e.privateKey),this.scopes=e.scopes||["*"]}sanitizePrivateKey(e){return e?e.replace(/\\n/g,`
2
- `).trim():""}async getCryptoKey(){if(this.cachedCryptoKey)return this.cachedCryptoKey;if(!this.rawPrivateKey)throw new Error("\u274C [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.");try{return this.cachedCryptoKey=await P(this.rawPrivateKey,"RS256"),this.cachedCryptoKey}catch(e){throw new Error(`\u274C [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${e?.message||e}`)}}async generateM2MToken(e){let t=await this.getCryptoKey(),s=Math.floor(Date.now()/1e3),i=e||this.scopes;return await new K({iss:this.apiKey,sub:this.apiKey,scopes:i}).setProtectedHeader({alg:"RS256",kid:this.keyId,typ:"JWT"}).setIssuedAt(s).setExpirationTime(s+3600).sign(t)}clearCache(){this.cachedCryptoKey=null}};var d=class{static encode(e){try{let t=typeof e=="object"&&e!==null?JSON.stringify(e):String(e);if(typeof window<"u"&&typeof window.btoa=="function"){let s=new TextEncoder().encode(t),i="";for(let o=0;o<s.length;o++){let c=s[o];c!==void 0&&(i+=String.fromCharCode(c))}return window.btoa(i)}return Buffer.from(t,"utf-8").toString("base64")}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al codificar payload: ${s}`)}}static decode(e){try{let t="";if(typeof window<"u"&&typeof window.atob=="function"){let s=window.atob(e),i=new Uint8Array(s.length);for(let o=0;o<s.length;o++)i[o]=s.charCodeAt(o);t=new TextDecoder().decode(i)}else t=Buffer.from(e,"base64").toString("utf-8");try{return JSON.parse(t)}catch{return t}}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${s}`)}}};var h=class{apiUrl;signer;userSessionToken=null;constructor(e){this.apiUrl="https://app-fpwuknh76a-uc.a.run.app".replace(/\/$/,"");let t={apiKey:e.clientId,keyId:e.privateKeyId,privateKey:e.privateKey};e.scopes!==void 0&&(t.scopes=e.scopes),this.signer=new l(t)}setUserSessionToken(e){this.userSessionToken=e}getUserSessionToken(){return this.userSessionToken}async request(e,t={}){let{body:s,headers:i,customScopes:o,method:c="GET",...k}=t,S=await this.signer.generateM2MToken(o),a=new Headers;a.set("Content-Type","application/json"),a.set("Accept","application/json"),a.set("Authorization",`Bearer ${S}`),this.userSessionToken&&a.set("x-leidenfrost-session",this.userSessionToken),i&&(i instanceof Headers?i.forEach((n,r)=>a.set(r,n)):Array.isArray(i)?i.forEach(([n,r])=>{n&&r&&a.set(n,r)}):Object.entries(i).forEach(([n,r])=>{r!==void 0&&a.set(n,String(r))}));let u;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let r=s.data?s:{data:d.encode(s)};u=JSON.stringify(r)}else u=String(s);let T=e.startsWith("/")?e:`/${e}`,b=`${this.apiUrl}${T}`,f={...k,method:c,headers:a};u!==void 0&&(f.body=u);let R=new Request(b,f);try{let n=await fetch(R),r=null,m=n.headers.get("content-type");if(m&&m.includes("application/json")?r=await n.json():r=await n.text(),!n.ok){let w=r&&typeof r=="object"?r:{},C={success:!1,status:n.status,message:typeof w.message=="string"?w.message:`Error HTTP ${n.status}: ${n.statusText}`,data:null};return Promise.reject(C)}return r}catch(n){if(n&&typeof n=="object"&&"success"in n)return Promise.reject(n);let r={success:!1,status:500,message:n instanceof Error?n.message:"Error de red o fallo de conexi\xF3n con la API.",data:null};return Promise.reject(r)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}};var g=class{http;constructor(e){this.http=e}async getSession(e){let t=await this.http.get(`/user/session?id=${e}`);return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}async postSession(e,t){let s=await this.http.post("/user/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async patchSession(e){let t=await this.http.patch("/user/session",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}async deleteSession(e){let t=await this.http.delete(`/user/session?refresh_token=${e}`);return t.success&&this.http.setUserSessionToken(null),t}async getUser(e){return await this.http.get(`/user?id=${e}`)}async postUser(e){return await this.http.post("/user",e)}async patchUser(e){return await this.http.patch("/user",e)}async deleteUser(){return await this.http.delete("/user")}};var y=class p{httpClient;user;constructor(e){if(!e.clientId||!e.privateKey)throw new Error("\u274C [Leidenfrost SDK]: La configuraci\xF3n inicial requiere 'clientId/apiKey' y 'privateKey'.");this.httpClient=new h(e),this.user=new g(this.httpClient)}static initializeApp(e){return new p(e)}setUserSessionToken(e){this.httpClient.setUserSessionToken(e)}getUserSessionToken(){return this.httpClient.getUserSessionToken()}},I=y;export{y as Leidenfrost,I as default};
1
+ import{SignJWT as v,importPKCS8 as A}from"jose";var d=class{apiKey;keyId;rawPrivateKey;scopes;cachedCryptoKey=null;constructor(e){this.apiKey=e.apiKey,this.keyId=e.keyId,this.rawPrivateKey=this.sanitizePrivateKey(e.privateKey),this.scopes=e.scopes||["*"]}sanitizePrivateKey(e){return e?e.replace(/\\n/g,`
2
+ `).trim():""}async getCryptoKey(){if(this.cachedCryptoKey)return this.cachedCryptoKey;if(!this.rawPrivateKey)throw new Error("\u274C [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.");try{return this.cachedCryptoKey=await A(this.rawPrivateKey,"RS256"),this.cachedCryptoKey}catch(e){throw new Error(`\u274C [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${e?.message||e}`)}}async generateM2MToken(e){let t=await this.getCryptoKey(),s=Math.floor(Date.now()/1e3),r=e||this.scopes;return await new v({iss:this.apiKey,sub:this.apiKey,scopes:r}).setProtectedHeader({alg:"RS256",kid:this.keyId,typ:"JWT"}).setIssuedAt(s).setExpirationTime(s+3600).sign(t)}clearCache(){this.cachedCryptoKey=null}};var h=class{static encode(e){try{let t=typeof e=="object"&&e!==null?JSON.stringify(e):String(e);if(typeof window<"u"&&typeof window.btoa=="function"){let s=new TextEncoder().encode(t),r="";for(let o=0;o<s.length;o++){let c=s[o];c!==void 0&&(r+=String.fromCharCode(c))}return window.btoa(r)}return Buffer.from(t,"utf-8").toString("base64")}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al codificar payload: ${s}`)}}static decode(e){try{let t="";if(typeof window<"u"&&typeof window.atob=="function"){let s=window.atob(e),r=new Uint8Array(s.length);for(let o=0;o<s.length;o++)r[o]=s.charCodeAt(o);t=new TextDecoder().decode(r)}else t=Buffer.from(e,"base64").toString("utf-8");try{return JSON.parse(t)}catch{return t}}catch(t){let s=t instanceof Error?t.message:String(t);throw new Error(`\u274C [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${s}`)}}};var f=class{apiUrl;signer;session=null;STORAGE_KEY="leidenfrost_session";constructor(e){this.apiUrl="https://app-fpwuknh76a-uc.a.run.app".replace(/\/$/,"");let t={apiKey:e.clientId,keyId:e.privateKeyId,privateKey:e.privateKey};if(e.scopes!==void 0&&(t.scopes=e.scopes),this.signer=new d(t),typeof window<"u"&&window.localStorage){let s=localStorage.getItem(this.STORAGE_KEY);if(s)try{this.session=JSON.parse(s)}catch{this.session=null}}}setSession(e){this.session=e,typeof window<"u"&&window.localStorage&&localStorage.setItem(this.STORAGE_KEY,JSON.stringify(e))}getSession(){return this.session}removeSession(){this.session=null,typeof window<"u"&&window.localStorage&&localStorage.removeItem(this.STORAGE_KEY)}async request(e,t={}){let{body:s,headers:r,customScopes:o,method:c="GET",...R}=t,b=await this.signer.generateM2MToken(o),a=new Headers;a.set("Content-Type","application/json"),a.set("Accept","application/json"),a.set("Authorization",`Bearer ${b}`),this.session?.authentication_token&&a.set("x-leidenfrost-session",this.session.authentication_token),r&&(r instanceof Headers?r.forEach((n,i)=>a.set(i,n)):Array.isArray(r)?r.forEach(([n,i])=>{n&&i&&a.set(n,i)}):Object.entries(r).forEach(([n,i])=>{i!==void 0&&a.set(n,String(i))}));let u;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let i=s.data?s:{data:h.encode(s)};u=JSON.stringify(i)}else u=String(s);let T=e.startsWith("/")?e:`/${e}`,k=`${this.apiUrl}${T}`,w={...R,method:c,headers:a};u!==void 0&&(w.body=u);let K=new Request(k,w);try{let n=await fetch(K),i=null,S=n.headers.get("content-type");if(S&&S.includes("application/json")?i=await n.json():i=await n.text(),n.status===401){this.removeSession(),typeof window<"u"&&(window.location.href="/");let l={success:!1,status:n.status,message:"Your session has expired",data:null};return Promise.reject(l)}if(!n.ok){let l=i&&typeof i=="object"?i:{},C={success:!1,status:n.status,message:typeof l.message=="string"?l.message:`Error HTTP ${n.status}: ${n.statusText}`,data:null};return Promise.reject(C)}return i}catch(n){if(n&&typeof n=="object"&&"success"in n)return Promise.reject(n);let i={success:!1,status:500,message:n instanceof Error?n.message:"Error de red o fallo de conexi\xF3n con la API.",data:null};return Promise.reject(i)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}};var y=class{http;constructor(e){this.http=e}async getUser(e){return await this.http.get(`/user?id=${e}`)}async postUser(e){return await this.http.post("/user",e)}async patchUser(e){return await this.http.patch("/user",e)}async deleteUser(){return await this.http.delete("/user")}};var g=class{http;constructor(e){this.http=e}async getSession(e){let t=await this.http.get(`/user/session?id=${e}`);return t.success&&t.data?.authentication_token&&this.http.setSession(t.data),t}async postSession(e,t){let s=await this.http.post("/user/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setSession(s.data),s}async patchSession(e){let t=await this.http.patch("/user/session",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setSession(t.data),t}async deleteSession(e){let t=await this.http.delete(`/user/session?refresh_token=${e}`);return t.success&&this.http.removeSession(),t}};var m=class p{httpClient;user;session;constructor(e){if(!e.clientId||!e.privateKey)throw new Error("\u274C [Leidenfrost SDK]: La configuraci\xF3n inicial requiere 'clientId/apiKey' y 'privateKey'.");this.httpClient=new f(e),this.user=new y(this.httpClient),this.session=new g(this.httpClient)}static initializeApp(e){return new p(e)}},M=m;export{m as Leidenfrost,M as default};
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/RsaSigner.ts","../src/core/Base64.ts","../src/core/HttpClient.ts","../src/modules/UserModule.ts","../src/index.ts"],"sourcesContent":["import { SignJWT, importPKCS8 } from \"jose\";\n\nexport interface RsaSignerOptions {\n apiKey: string;\n keyId: string;\n privateKey: string;\n scopes?: string[] | undefined;\n}\n\nexport class RsaSigner {\n private apiKey: string;\n private keyId: string;\n private rawPrivateKey: string;\n private scopes: string[];\n private cachedCryptoKey: CryptoKey | null = null;\n\n constructor(options: RsaSignerOptions) {\n this.apiKey = options.apiKey;\n this.keyId = options.keyId;\n this.rawPrivateKey = this.sanitizePrivateKey(options.privateKey);\n this.scopes = options.scopes || [\"*\"];\n }\n\n /**\n * Reemplaza saltos de línea escapados por saltos de línea reales PEM\n */\n private sanitizePrivateKey(key: string): string {\n if (!key) return \"\";\n return key.replace(/\\\\n/g, \"\\n\").trim();\n }\n\n /**\n * Obtiene e importa la llave privada PKCS#8 a WebCrypto, utilizando caché en memoria\n */\n private async getCryptoKey(): Promise<CryptoKey> {\n if (this.cachedCryptoKey) {\n return this.cachedCryptoKey;\n }\n\n if (!this.rawPrivateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.\"\n );\n }\n\n try {\n this.cachedCryptoKey = (await importPKCS8(\n this.rawPrivateKey,\n \"RS256\"\n )) as CryptoKey;\n return this.cachedCryptoKey;\n } catch (error: any) {\n throw new Error(\n `❌ [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${error?.message || error}`\n );\n }\n }\n\n /**\n * Genera un JWT de Service Account firmado con RS256 (válido por 1 hora)\n */\n public async generateM2MToken(customScopes?: string[]): Promise<string> {\n const cryptoKey = await this.getCryptoKey();\n const now = Math.floor(Date.now() / 1000);\n const targetScopes = customScopes || this.scopes;\n\n return await new SignJWT({\n iss: this.apiKey,\n sub: this.apiKey,\n scopes: targetScopes,\n })\n .setProtectedHeader({ alg: \"RS256\", kid: this.keyId, typ: \"JWT\" })\n .setIssuedAt(now)\n .setExpirationTime(now + 3600)\n .sign(cryptoKey);\n }\n\n /**\n * Limpia la caché de la llave procesada\n */\n public clearCache(): void {\n this.cachedCryptoKey = null;\n }\n}\n\n","export class Base64 {\n /**\n * Codifica un objeto o cadena en Base64 con soporte UTF-8\n */\n public static encode(data: unknown): string {\n try {\n const jsonString =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data)\n : String(data);\n\n if (typeof window !== \"undefined\" && typeof window.btoa === \"function\") {\n const utf8Bytes = new TextEncoder().encode(jsonString);\n let binaryString = \"\";\n for (let i = 0; i < utf8Bytes.length; i++) {\n const byte = utf8Bytes[i];\n if (byte !== undefined) {\n binaryString += String.fromCharCode(byte);\n }\n }\n return window.btoa(binaryString);\n }\n\n // Entorno Node.js\n return Buffer.from(jsonString, \"utf-8\").toString(\"base64\");\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al codificar payload: ${msg}`);\n }\n }\n\n /**\n * Decodifica una cadena Base64\n */\n public static decode<T = unknown>(base64String: string): T {\n try {\n let jsonString = \"\";\n\n if (typeof window !== \"undefined\" && typeof window.atob === \"function\") {\n const binaryString = window.atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n jsonString = new TextDecoder().decode(bytes);\n } else {\n jsonString = Buffer.from(base64String, \"base64\").toString(\"utf-8\");\n }\n\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${msg}`);\n }\n }\n}","import { RsaSigner } from \"./RsaSigner.js\";\nimport type { RsaSignerOptions } from \"./RsaSigner.js\";\nimport { Base64 } from \"./Base64.js\";\n\nexport interface HttpRequestOptions extends Omit<RequestInit, \"body\"> {\n body?: unknown;\n customScopes?: string[];\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data: T;\n status?: number;\n}\n\nexport interface HttpClientConfig {\n type: string;\n clientId: string;\n clientEmail: string;\n privateKeyId: string;\n privateKey: string;\n scopes?: string[];\n}\n\n\nexport class HttpClient {\n private apiUrl: string;\n private signer: RsaSigner;\n private userSessionToken: string | null = null;\n\n constructor(config: HttpClientConfig) {\n this.apiUrl = \"https://app-fpwuknh76a-uc.a.run.app\".replace(/\\/$/, \"\");\n\n const signerOpts: RsaSignerOptions = {\n apiKey: config.clientId,\n keyId: config.privateKeyId,\n privateKey: config.privateKey,\n };\n\n if (config.scopes !== undefined) {\n signerOpts.scopes = config.scopes;\n }\n\n this.signer = new RsaSigner(signerOpts);\n }\n\n public setUserSessionToken(token: string | null): void {\n this.userSessionToken = token;\n }\n\n public getUserSessionToken(): string | null {\n return this.userSessionToken;\n }\n\n public async request<T = unknown>(\n endpoint: string,\n options: HttpRequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { body, headers, customScopes, method = \"GET\", ...restOptions } = options;\n\n const m2mToken = await this.signer.generateM2MToken(customScopes);\n\n // 1. Cabeceras con objeto Headers nativo\n const requestHeaders = new Headers();\n requestHeaders.set(\"Content-Type\", \"application/json\");\n requestHeaders.set(\"Accept\", \"application/json\");\n requestHeaders.set(\"Authorization\", `Bearer ${m2mToken}`);\n\n if (this.userSessionToken) {\n requestHeaders.set(\"x-leidenfrost-session\", this.userSessionToken);\n }\n\n if (headers) {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => requestHeaders.set(key, value));\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n if (key && value) requestHeaders.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) requestHeaders.set(key, String(value));\n });\n }\n }\n\n // 2. Procesamiento del Body\n let requestBody: string | undefined = undefined;\n if (body !== undefined && body !== null) {\n if (typeof body === \"object\" && !(body instanceof FormData)) {\n const bodyRecord = body as Record<string, unknown>;\n const payloadToEncode = bodyRecord[\"data\"] ? body : { data: Base64.encode(body) };\n requestBody = JSON.stringify(payloadToEncode);\n } else {\n requestBody = String(body);\n }\n }\n\n const cleanEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n const fullUrl = `${this.apiUrl}${cleanEndpoint}`;\n\n // 3. Objeto de opciones flexible\n const requestInitOptions: Record<string, unknown> = {\n ...(restOptions as Record<string, unknown>),\n method: method as string,\n headers: requestHeaders,\n };\n\n if (requestBody !== undefined) {\n requestInitOptions[\"body\"] = requestBody;\n }\n\n // 4. Instancia de Request limpia\n const requestInstance = new Request(fullUrl, requestInitOptions as unknown as RequestInit);\n\n try {\n const response = await fetch(requestInstance);\n\n let responseData: unknown = null;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType && contentType.includes(\"application/json\")) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (!response.ok) {\n const errorRecord = (responseData && typeof responseData === \"object\") ? (responseData as Record<string, unknown>) : {};\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: typeof errorRecord[\"message\"] === \"string\" ? errorRecord[\"message\"] : `Error HTTP ${response.status}: ${response.statusText}`,\n data: null,\n };\n return Promise.reject(errorResult);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error: unknown) {\n if (error && typeof error === \"object\" && \"success\" in error) {\n return Promise.reject(error);\n }\n\n const networkError: ApiResponse<null> = {\n success: false,\n status: 500,\n message: error instanceof Error ? error.message : \"Error de red o fallo de conexión con la API.\",\n data: null,\n };\n return Promise.reject(networkError);\n }\n }\n\n public get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n public post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n public put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n public patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PATCH\", body });\n }\n\n public delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface User {\n id?: string;\n tenant_id?:string;\n email: string;\n password?: string;\n name: string;\n last_name: string;\n telephone?: string;\n role?: \"messiah\" | \"client\" | \"admin\" | \"customer\";\n membership?: {\n name: string;\n level: number;\n points: number;\n coupons: unknown[];\n };\n enabled?: boolean;\n created_at?: unknown;\n update_at?: unknown;\n}\n\nexport interface Session {\n user: User;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport class UserModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n /**\n * Module: Session\n * Ruta: /user/session\n */\n public async getSession(id:string): Promise<ApiResponse<Session>> {\n const response = await this.http.get<Session>(`/user/session?id=${id}`);\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async postSession(email: string, password: string): Promise<ApiResponse<Session>> {\n const response = await this.http.post<Session>(\"/user/session\", { email, password });\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async patchSession(refreshToken: string): Promise<ApiResponse<Session>> {\n const response = await this.http.patch<Session>(\"/user/session\", { refresh_token: refreshToken });\n if (response.success && response.data?.authentication_token) {\n this.http.setUserSessionToken(response.data.authentication_token);\n }\n return response;\n }\n\n public async deleteSession(refreshToken: string): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(`/user/session?refresh_token=${refreshToken}`);\n if (response.success) {\n this.http.setUserSessionToken(null);\n }\n return response;\n }\n\n /**\n * Module: USER\n * Ruta: /user\n */\n public async getUser(id:string): Promise<ApiResponse<User>> {\n const response = await this.http.get<User>(`/user?id=${id}`);\n return response;\n }\n public async postUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.post<User>(\"/user\", data);\n return response;\n }\n public async patchUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.patch<User>(\"/user\", data);\n return response;\n }\n public async deleteUser(): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(\"/user\");\n return response;\n }\n}","import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig } from \"./core/HttpClient.js\";\nimport { UserModule } from \"./modules/UserModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\n\nexport type {\n User,\n Session,\n} from \"./modules/UserModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public user: UserModule;\n\n constructor(config: HttpClientConfig) {\n if (!config.clientId || !config.privateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La configuración inicial requiere 'clientId/apiKey' y 'privateKey'.\"\n );\n }\n\n this.httpClient = new HttpClient(config);\n this.user = new UserModule(this.httpClient);\n }\n\n public static initializeApp(config: HttpClientConfig): Leidenfrost {\n return new Leidenfrost(config);\n }\n\n public setUserSessionToken(token: string | null): void {\n this.httpClient.setUserSessionToken(token);\n }\n\n public getUserSessionToken(): string | null {\n return this.httpClient.getUserSessionToken();\n }\n}\n\nexport default Leidenfrost;"],"mappings":"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","names":["SignJWT","importPKCS8","RsaSigner","options","key","error","customScopes","cryptoKey","now","targetScopes","Base64","data","jsonString","utf8Bytes","binaryString","i","byte","error","msg","base64String","bytes","HttpClient","config","signerOpts","RsaSigner","token","endpoint","options","body","headers","customScopes","method","restOptions","m2mToken","requestHeaders","value","key","requestBody","payloadToEncode","Base64","cleanEndpoint","fullUrl","requestInitOptions","requestInstance","response","responseData","contentType","errorRecord","errorResult","error","networkError","UserModule","httpClient","id","response","email","password","refreshToken","data","Leidenfrost","_Leidenfrost","config","HttpClient","UserModule","token","index_default"]}
1
+ {"version":3,"sources":["../src/core/RsaSigner.ts","../src/core/Base64.ts","../src/core/HttpClient.ts","../src/modules/UserModule.ts","../src/modules/SessionModule.ts","../src/index.ts"],"sourcesContent":["import { SignJWT, importPKCS8 } from \"jose\";\n\nexport interface RsaSignerOptions {\n apiKey: string;\n keyId: string;\n privateKey: string;\n scopes?: string[] | undefined;\n}\n\nexport class RsaSigner {\n private apiKey: string;\n private keyId: string;\n private rawPrivateKey: string;\n private scopes: string[];\n private cachedCryptoKey: CryptoKey | null = null;\n\n constructor(options: RsaSignerOptions) {\n this.apiKey = options.apiKey;\n this.keyId = options.keyId;\n this.rawPrivateKey = this.sanitizePrivateKey(options.privateKey);\n this.scopes = options.scopes || [\"*\"];\n }\n\n /**\n * Reemplaza saltos de línea escapados por saltos de línea reales PEM\n */\n private sanitizePrivateKey(key: string): string {\n if (!key) return \"\";\n return key.replace(/\\\\n/g, \"\\n\").trim();\n }\n\n /**\n * Obtiene e importa la llave privada PKCS#8 a WebCrypto, utilizando caché en memoria\n */\n private async getCryptoKey(): Promise<CryptoKey> {\n if (this.cachedCryptoKey) {\n return this.cachedCryptoKey;\n }\n\n if (!this.rawPrivateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La 'privateKey' en formato PEM es requerida para firmar el token RS256.\"\n );\n }\n\n try {\n this.cachedCryptoKey = (await importPKCS8(\n this.rawPrivateKey,\n \"RS256\"\n )) as CryptoKey;\n return this.cachedCryptoKey;\n } catch (error: any) {\n throw new Error(\n `❌ [Leidenfrost SDK]: Fallo al importar la llave privada PKCS#8 RS256: ${error?.message || error}`\n );\n }\n }\n\n /**\n * Genera un JWT de Service Account firmado con RS256 (válido por 1 hora)\n */\n public async generateM2MToken(customScopes?: string[]): Promise<string> {\n const cryptoKey = await this.getCryptoKey();\n const now = Math.floor(Date.now() / 1000);\n const targetScopes = customScopes || this.scopes;\n\n return await new SignJWT({\n iss: this.apiKey,\n sub: this.apiKey,\n scopes: targetScopes,\n })\n .setProtectedHeader({ alg: \"RS256\", kid: this.keyId, typ: \"JWT\" })\n .setIssuedAt(now)\n .setExpirationTime(now + 3600)\n .sign(cryptoKey);\n }\n\n /**\n * Limpia la caché de la llave procesada\n */\n public clearCache(): void {\n this.cachedCryptoKey = null;\n }\n}\n\n","export class Base64 {\n /**\n * Codifica un objeto o cadena en Base64 con soporte UTF-8\n */\n public static encode(data: unknown): string {\n try {\n const jsonString =\n typeof data === \"object\" && data !== null\n ? JSON.stringify(data)\n : String(data);\n\n if (typeof window !== \"undefined\" && typeof window.btoa === \"function\") {\n const utf8Bytes = new TextEncoder().encode(jsonString);\n let binaryString = \"\";\n for (let i = 0; i < utf8Bytes.length; i++) {\n const byte = utf8Bytes[i];\n if (byte !== undefined) {\n binaryString += String.fromCharCode(byte);\n }\n }\n return window.btoa(binaryString);\n }\n\n // Entorno Node.js\n return Buffer.from(jsonString, \"utf-8\").toString(\"base64\");\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al codificar payload: ${msg}`);\n }\n }\n\n /**\n * Decodifica una cadena Base64\n */\n public static decode<T = unknown>(base64String: string): T {\n try {\n let jsonString = \"\";\n\n if (typeof window !== \"undefined\" && typeof window.atob === \"function\") {\n const binaryString = window.atob(base64String);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n jsonString = new TextDecoder().decode(bytes);\n } else {\n jsonString = Buffer.from(base64String, \"base64\").toString(\"utf-8\");\n }\n\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`❌ [Leidenfrost SDK - Base64]: Error al decodificar cadena: ${msg}`);\n }\n }\n}","import { RsaSigner } from \"./RsaSigner.js\";\nimport type { RsaSignerOptions } from \"./RsaSigner.js\";\nimport { Base64 } from \"./Base64.js\";\nimport type { Session } from \"../modules/SessionModule.js\";\n\nexport interface HttpRequestOptions extends Omit<RequestInit, \"body\"> {\n body?: unknown;\n customScopes?: string[];\n}\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n message?: string;\n data: T;\n status?: number;\n}\n\nexport interface HttpClientConfig {\n type: string;\n clientId: string;\n clientEmail: string;\n privateKeyId: string;\n privateKey: string;\n scopes?: string[];\n}\n\n\nexport class HttpClient {\n private apiUrl: string;\n private signer: RsaSigner;\n\n private session: Session | null = null;\n private readonly STORAGE_KEY = 'leidenfrost_session';\n\n constructor(config: HttpClientConfig) {\n this.apiUrl = \"https://app-fpwuknh76a-uc.a.run.app\".replace(/\\/$/, \"\");\n\n const signerOpts: RsaSignerOptions = {\n apiKey: config.clientId,\n keyId: config.privateKeyId,\n privateKey: config.privateKey,\n };\n\n if (config.scopes !== undefined) {\n signerOpts.scopes = config.scopes;\n }\n\n this.signer = new RsaSigner(signerOpts);\n \n if (typeof window !== 'undefined' && window.localStorage) {\n const saved = localStorage.getItem(this.STORAGE_KEY);\n if (saved) {\n try {\n this.session = JSON.parse(saved);\n } catch {\n this.session = null;\n }\n }\n }\n }\n\n public setSession(sessionData: Session): void {\n this.session = sessionData;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(sessionData));\n }\n }\n\n public getSession(): Session | null {\n return this.session;\n }\n\n public removeSession(): void {\n this.session = null;\n if (typeof window !== 'undefined' && window.localStorage) {\n localStorage.removeItem(this.STORAGE_KEY);\n }\n }\n\n public async request<T = unknown>(\n endpoint: string,\n options: HttpRequestOptions = {}\n ): Promise<ApiResponse<T>> {\n const { body, headers, customScopes, method = \"GET\", ...restOptions } = options;\n\n const m2mToken = await this.signer.generateM2MToken(customScopes);\n\n // 1. Cabeceras con objeto Headers nativo\n const requestHeaders = new Headers();\n requestHeaders.set(\"Content-Type\", \"application/json\");\n requestHeaders.set(\"Accept\", \"application/json\");\n requestHeaders.set(\"Authorization\", `Bearer ${m2mToken}`);\n\n if (this.session?.authentication_token) {\n requestHeaders.set(\"x-leidenfrost-session\", this.session.authentication_token);\n }\n\n if (headers) {\n if (headers instanceof Headers) {\n headers.forEach((value, key) => requestHeaders.set(key, value));\n } else if (Array.isArray(headers)) {\n headers.forEach(([key, value]) => {\n if (key && value) requestHeaders.set(key, value);\n });\n } else {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) requestHeaders.set(key, String(value));\n });\n }\n }\n\n // 2. Procesamiento del Body\n let requestBody: string | undefined = undefined;\n if (body !== undefined && body !== null) {\n if (typeof body === \"object\" && !(body instanceof FormData)) {\n const bodyRecord = body as Record<string, unknown>;\n const payloadToEncode = bodyRecord[\"data\"] ? body : { data: Base64.encode(body) };\n requestBody = JSON.stringify(payloadToEncode);\n } else {\n requestBody = String(body);\n }\n }\n\n const cleanEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n const fullUrl = `${this.apiUrl}${cleanEndpoint}`;\n\n // 3. Objeto de opciones flexible\n const requestInitOptions: Record<string, unknown> = {\n ...(restOptions as Record<string, unknown>),\n method: method as string,\n headers: requestHeaders,\n };\n\n if (requestBody !== undefined) {\n requestInitOptions[\"body\"] = requestBody;\n }\n\n // 4. Instancia de Request limpia\n const requestInstance = new Request(fullUrl, requestInitOptions as unknown as RequestInit);\n\n try {\n const response = await fetch(requestInstance);\n\n let responseData: unknown = null;\n const contentType = response.headers.get(\"content-type\");\n\n if (contentType && contentType.includes(\"application/json\")) {\n responseData = await response.json();\n } else {\n responseData = await response.text();\n }\n\n if (response.status === 401) {\n this.removeSession();\n \n // Opcional: Redirigir directamente al login si estás en el cliente\n if (typeof window !== 'undefined') {\n window.location.href = '/';\n }\n\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: \"Your session has expired\",\n data: null,\n };\n\n return Promise.reject(errorResult);\n }\n\n if (!response.ok) {\n const errorRecord = (responseData && typeof responseData === \"object\") ? (responseData as Record<string, unknown>) : {};\n const errorResult: ApiResponse<null> = {\n success: false,\n status: response.status,\n message: typeof errorRecord[\"message\"] === \"string\" ? errorRecord[\"message\"] : `Error HTTP ${response.status}: ${response.statusText}`,\n data: null,\n };\n return Promise.reject(errorResult);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error: unknown) {\n if (error && typeof error === \"object\" && \"success\" in error) {\n return Promise.reject(error);\n }\n\n const networkError: ApiResponse<null> = {\n success: false,\n status: 500,\n message: error instanceof Error ? error.message : \"Error de red o fallo de conexión con la API.\",\n data: null,\n };\n return Promise.reject(networkError);\n }\n }\n\n public get<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"GET\" });\n }\n\n public post<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"POST\", body });\n }\n\n public put<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PUT\", body });\n }\n\n public patch<T = unknown>(endpoint: string, body?: unknown, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"PATCH\", body });\n }\n\n public delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>> {\n return this.request<T>(endpoint, { ...options, method: \"DELETE\" });\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface User {\n id?: string;\n tenant_id?:string;\n email: string;\n password?: string;\n name: string;\n last_name: string;\n telephone?: string;\n role?: \"messiah\" | \"client\" | \"admin\" | \"customer\";\n membership?: {\n name: string;\n level: number;\n points: number;\n coupons: unknown[];\n };\n enabled?: boolean;\n created_at?: unknown;\n update_at?: unknown;\n}\n\nexport class UserModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n /**\n * Module: USER\n * Ruta: /user\n */\n public async getUser(id:string): Promise<ApiResponse<User>> {\n const response = await this.http.get<User>(`/user?id=${id}`);\n return response;\n }\n public async postUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.post<User>(\"/user\", data);\n return response;\n }\n public async patchUser(data: User): Promise<ApiResponse<User>> {\n const response = await this.http.patch<User>(\"/user\", data);\n return response;\n }\n public async deleteUser(): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(\"/user\");\n return response;\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\nimport type { User } from \"./UserModule.js\";\n\nexport interface Session {\n user: User;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport class SessionModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n /**\n * Module: Session\n * Ruta: /user/session\n */\n public async getSession(id:string): Promise<ApiResponse<Session>> {\n const response = await this.http.get<Session>(`/user/session?id=${id}`);\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async postSession(email: string, password: string): Promise<ApiResponse<Session>> {\n const response = await this.http.post<Session>(\"/user/session\", { email, password });\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async patchSession(refreshToken: string): Promise<ApiResponse<Session>> {\n const response = await this.http.patch<Session>(\"/user/session\", { refresh_token: refreshToken });\n if (response.success && response.data?.authentication_token) {\n this.http.setSession(response.data);\n }\n return response;\n }\n\n public async deleteSession(refreshToken: string): Promise<ApiResponse<null>> {\n const response = await this.http.delete<null>(`/user/session?refresh_token=${refreshToken}`);\n if (response.success) {\n this.http.removeSession();\n }\n return response;\n }\n}","import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig } from \"./core/HttpClient.js\";\nimport { UserModule } from \"./modules/UserModule.js\";\nimport { SessionModule } from \"./modules/SessionModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\n\nexport type {\n User,\n} from \"./modules/UserModule.js\";\n\nexport type {\n Session,\n} from \"./modules/SessionModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public user: UserModule;\n public session : SessionModule;\n\n constructor(config: HttpClientConfig) {\n if (!config.clientId || !config.privateKey) {\n throw new Error(\n \"❌ [Leidenfrost SDK]: La configuración inicial requiere 'clientId/apiKey' y 'privateKey'.\"\n );\n }\n\n this.httpClient = new HttpClient(config);\n this.user = new UserModule(this.httpClient);\n this.session = new SessionModule(this.httpClient);\n }\n\n public static initializeApp(config: HttpClientConfig): Leidenfrost {\n return new Leidenfrost(config);\n }\n}\n\nexport default Leidenfrost;"],"mappings":"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","names":["SignJWT","importPKCS8","RsaSigner","options","key","error","customScopes","cryptoKey","now","targetScopes","Base64","data","jsonString","utf8Bytes","binaryString","i","byte","error","msg","base64String","bytes","HttpClient","config","signerOpts","RsaSigner","saved","sessionData","endpoint","options","body","headers","customScopes","method","restOptions","m2mToken","requestHeaders","value","key","requestBody","payloadToEncode","Base64","cleanEndpoint","fullUrl","requestInitOptions","requestInstance","response","responseData","contentType","errorResult","errorRecord","error","networkError","UserModule","httpClient","id","data","SessionModule","httpClient","id","response","email","password","refreshToken","Leidenfrost","_Leidenfrost","config","HttpClient","UserModule","SessionModule","index_default"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leidenfrost/sdk",
3
- "version": "0.1.0-alpha.2",
3
+ "version": "0.1.0-alpha.4",
4
4
  "type": "module",
5
5
  "description": "SDK Oficial de Leidenfrost Platform para autenticación M2M y gestión Multi-Tenant",
6
6
  "main": "./dist/index.cjs",