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

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/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var S=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var U=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var D=(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 n of U(e))!_.call(o,n)&&n!==t&&S(o,n,{get:()=>e[n],enumerable:!(s=v(e,n))||s.enumerable});return o};var H=o=>x(S({},"__esModule",{value:!0}),o);var j={};D(j,{Leidenfrost:()=>f,default:()=>E});module.exports=H(j);var d=require("jose"),u=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),n=e||this.scopes;return await new d.SignJWT({iss:this.apiKey,sub:this.apiKey,scopes:n}).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),n="";for(let a=0;a<s.length;a++){let p=s[a];p!==void 0&&(n+=String.fromCharCode(p))}return window.btoa(n)}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),n=new Uint8Array(s.length);for(let a=0;a<s.length;a++)n[a]=s.charCodeAt(a);t=new TextDecoder().decode(n)}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 u(t)}setUserSessionToken(e){this.userSessionToken=e}getUserSessionToken(){return this.userSessionToken}async request(e,t={}){let{body:s,headers:n,customScopes:a,method:p="GET",...A}=t,k=await this.signer.generateM2MToken(a),c=new Headers;c.set("Content-Type","application/json"),c.set("Accept","application/json"),c.set("Authorization",`Bearer ${k}`),this.userSessionToken&&c.set("X-User-Session",this.userSessionToken),n&&(n instanceof Headers?n.forEach((r,i)=>c.set(i,r)):Array.isArray(n)?n.forEach(([r,i])=>{r&&i&&c.set(r,i)}):Object.entries(n).forEach(([r,i])=>{i!==void 0&&c.set(r,String(i))}));let l;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let i=s.data?s:{data:h.encode(s)};l=JSON.stringify(i)}else l=String(s);let C=e.startsWith("/")?e:`/${e}`,P=`${this.apiUrl}${C}`,R={...A,method:p,headers:c};l!==void 0&&(R.body=l);let T=new Request(P,R);try{let r=await fetch(T),i=null,w=r.headers.get("content-type");if(w&&w.includes("application/json")?i=await r.json():i=await r.text(),!r.ok){let b=i&&typeof i=="object"?i:{},K={success:!1,status:r.status,message:typeof b.message=="string"?b.message:`Error HTTP ${r.status}: ${r.statusText}`,data:null};return Promise.reject(K)}return i}catch(r){if(r&&typeof r=="object"&&"success"in r)return Promise.reject(r);let i={success:!1,status:500,message:r instanceof Error?r.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 loginMessiah(e,t){let s=await this.http.post("/user/messiah/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerClient(e){return this.http.post("/user/client",e)}async loginClient(e,t){let s=await this.http.post("/user/client/session/",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerAdmin(e){return this.http.post("/user/admin",e)}async loginAdmin(e,t){let s=await this.http.post("/user/admin/session/",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerCustomer(e){return this.http.post("/user/costumer",e)}async loginCustomer(e,t){let s=await this.http.post("/user/costumer/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async refreshSession(e){let t=await this.http.post("/user/session/refresh",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}logout(){this.http.setUserSessionToken(null)}};var m=class{http;constructor(e){this.http=e}async createApp(e){return this.http.post("/operational/apps",e)}async listAppsByTenant(e){return this.http.get(`/operational/apps?tenant_id=${encodeURIComponent(e)}`)}async getAppDetail(e){return this.http.get(`/operational/apps?app_id=${e}`)}async updateApp(e,t){return this.http.put(`/operational/apps?app_id=${e}`,t)}async deleteApp(e){return this.http.delete(`/operational/apps?app_id=${e}`)}async createServiceAccount(e){return this.http.post("/operational/apps/service-account",e)}async createServiceAccountAndDownload(e){let t=await this.createServiceAccount(e);if(t.success&&t.data){let s=`${t.data.client_id||"service-account"}.json`;this.triggerJsonDownload(t.data,s)}return t}triggerJsonDownload(e,t){if(typeof window>"u"||typeof document>"u")return;let s=JSON.stringify(e,null,2),n=new Blob([s],{type:"application/json"}),a=URL.createObjectURL(n),p=document.createElement("a");p.href=a,p.download=t,document.body.appendChild(p),p.click(),document.body.removeChild(p),URL.revokeObjectURL(a)}async listSDkReleases(e){let t=e?`/operational/sdks?channel=${e}`:"/operational/sdks";return this.http.get(t)}async publishSDKRelease(e){return this.http.post("/operational/sdks",e)}async deleteSDKReleases(e){return this.http.delete(`/operational/sdks?id=${e}`)}};var f=class o{httpClient;auth;operational;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.auth=new y(this.httpClient),this.operational=new m(this.httpClient)}static initializeApp(e){return new o(e)}setUserSessionToken(e){this.httpClient.setUserSessionToken(e)}getUserSessionToken(){return this.httpClient.getUserSessionToken()}},E=f;0&&(module.exports={Leidenfrost});
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});
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/AuthModule.ts","../src/modules/OperationalModule.ts"],"sourcesContent":["import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\nimport { AuthModule } from \"./modules/AuthModule.js\";\nimport { OperationalModule } from \"./modules/OperationalModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\nexport type { UserRecord, UserSessionData, CreateUserPayload } from \"./modules/AuthModule.js\";\nexport type {\n AppRecord,\n CreateAppPayload,\n AppPlatform,\n CreateServiceAccountPayload,\n ServiceAccountCredentials,\n SDKRecord,\n PublishSDKPayload,\n SDKChannel\n} from \"./modules/OperationalModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public auth: AuthModule;\n public operational: OperationalModule;\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.auth = new AuthModule(this.httpClient);\n this.operational = new OperationalModule(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-User-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}","\nimport type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface UserRecord {\n id: string;\n email: 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}\n\nexport interface UserSessionData {\n user: UserRecord;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport interface CreateUserPayload {\n email: string;\n password: string;\n name: string;\n last_name: string;\n telephone?: string;\n [key: string]: unknown;\n}\n\nexport class AuthModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n // ==========================================\n // 1. MESSIAH (SuperAdmin Platform)\n // ==========================================\n /**\n * Iniciar Sesión Messiah (Etapa 2: Login)\n * Ruta: POST /user/messiah/session\n */\n public async loginMessiah(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/messiah/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 // ==========================================\n // 2. CLIENT (Tenant B2B Owner)\n // ==========================================\n\n /**\n * Crear usuario Client/Tenant (Etapa 1: Registro)\n * Ruta: POST /user/client\n */\n public async registerClient(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/client\", data);\n }\n\n /**\n * Iniciar Sesión Client (Etapa 2: Login)\n * Ruta: POST /user/client/session/\n */\n public async loginClient(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/client/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 // ==========================================\n // 3. ADMIN (Personal Operativo del Tenant)\n // ==========================================\n\n /**\n * Crear usuario Admin (Etapa 1: Registro)\n * Ruta: POST /user/admin\n */\n public async registerAdmin(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/admin\", data);\n }\n\n /**\n * Iniciar Sesión Admin (Etapa 2: Login)\n * Ruta: POST /user/admin/session/\n */\n public async loginAdmin(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/admin/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 // ==========================================\n // 4. CUSTOMER (Comprador Final B2C)\n // ==========================================\n\n /**\n * Crear usuario Customer (Etapa 1: Registro)\n * Ruta: POST /user/costumer\n */\n public async registerCustomer(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/costumer\", data);\n }\n\n /**\n * Iniciar Sesión Customer (Etapa 2: Login)\n * Ruta: POST /user/costumer/session\n */\n public async loginCustomer(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/costumer/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 // ==========================================\n // GESTIÓN DE SESIÓN Y REFRESH TOKEN\n // ==========================================\n\n /**\n * Renovar el token de acceso expirado mediante el Refresh Token\n * Ruta: POST /user/session/refresh\n */\n public async refreshSession(refreshToken: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/session/refresh\", { 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 /**\n * Cierra la sesión en el SDK\n */\n public logout(): void {\n this.http.setUserSessionToken(null);\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport type AppPlatform = \"web\" | \"ios\" | \"android\" | \"pos\";\nexport type SDKChannel = \"alpha\" | \"beta\" | \"stable\";\n\nexport interface AppRecord {\n id: string;\n app_id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n platform: AppPlatform;\n enabled: boolean;\n created_at?: unknown;\n updated_at?: unknown;\n}\n\nexport interface CreateAppPayload {\n name: string;\n tenant_id: string;\n description?: string;\n platform?: AppPlatform;\n}\n\nexport interface CreateServiceAccountPayload {\n client_email: string;\n app_id: string;\n allowed_scopes?: string[];\n}\n\nexport interface ServiceAccountCredentials {\n type: \"service_account\";\n client_id: string;\n client_email: string;\n app_id: string;\n tenant_id: string;\n private_key_id: string;\n private_key: string;\n scopes: string[];\n}\n\n\nexport interface SDKRecord {\n release_id: string;\n name: string;\n description: string;\n channel: SDKChannel;\n version: string;\n min_node_version: string;\n changelog: string[];\n download_url: string;\n public: boolean;\n enabled: boolean;\n created_at: string;\n}\n\nexport interface PublishSDKPayload {\n version: string;\n channel?: SDKChannel;\n changelog?: string[];\n download_url: string;\n public: boolean;\n min_node_version?: string;\n}\n\n\nexport class OperationalModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n // ==========================================\n // CRUD DE APLICACIONES (POST, GET, PUT, DELETE)\n // Ruta Base: /operational/apps\n // ==========================================\n\n /**\n * Registrar una nueva Aplicación vinculada a un Tenant\n * Ruta: POST /operational/apps\n */\n public async createApp(payload: CreateAppPayload): Promise<ApiResponse<AppRecord>> {\n return this.http.post<AppRecord>(\"/operational/apps\", payload);\n }\n\n /**\n * Obtener todas las Aplicaciones de un Tenant\n * Ruta: GET /operational/apps?tenant_id=xxx\n */\n public async listAppsByTenant(tenantId: string): Promise<ApiResponse<AppRecord[]>> {\n return this.http.get<AppRecord[]>(`/operational/apps?tenant_id=${encodeURIComponent(tenantId)}`);\n }\n\n /**\n * Obtener detalle de una Aplicación por su app_id o id de documento\n * Ruta: GET /operational/apps/:appId\n */\n public async getAppDetail(appId: string): Promise<ApiResponse<AppRecord>> {\n return this.http.get<AppRecord>(`/operational/apps?app_id=${appId}`);\n }\n\n /**\n * Actualizar datos de una Aplicación\n * Ruta: PUT /operational/apps/:appId\n */\n public async updateApp(\n appId: string,\n payload: Partial<Omit<AppRecord, \"id\" | \"app_id\" | \"tenant_id\" | \"created_at\">>\n ): Promise<ApiResponse<AppRecord>> {\n return this.http.put<AppRecord>(`/operational/apps?app_id=${appId}`, payload);\n }\n\n /**\n * Deshabilitar / Eliminar una Aplicación\n * Ruta: DELETE /operational/apps/:appId\n */\n public async deleteApp(appId: string): Promise<ApiResponse<{ id: string; deleted: boolean }>> {\n return this.http.delete<{ id: string; deleted: boolean }>(`/operational/apps?app_id=${appId}`);\n }\n\n// ==========================================\n // SERVICE ACCOUNTS (/operational/apps/service-account)\n // ==========================================\n\n /**\n * Genera una Service Account y retorna sus credenciales (incluyendo PKCS#8 Private Key)\n * Ruta: POST /operational/apps/service-account\n */\n public async createServiceAccount(\n payload: CreateServiceAccountPayload\n ): Promise<ApiResponse<ServiceAccountCredentials>> {\n return this.http.post<ServiceAccountCredentials>(\"/operational/apps/service-account\", payload);\n }\n\n /**\n * Genera una Service Account e inicie la descarga automática del archivo JSON de credenciales en el navegador\n * Ruta: POST /operational/apps/service-account\n */\n public async createServiceAccountAndDownload(\n payload: CreateServiceAccountPayload\n ): Promise<ApiResponse<ServiceAccountCredentials>> {\n const response = await this.createServiceAccount(payload);\n\n if (response.success && response.data) {\n const fileName = `${response.data.client_id || \"service-account\"}.json`;\n this.triggerJsonDownload(response.data, fileName);\n }\n\n return response;\n }\n\n /**\n * Utilería del cliente para forzar la descarga del .json en el navegador (Estilo Firebase / GCP)\n */\n private triggerJsonDownload(data: object, filename: string): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return; // Prevenir ejecución en Server-Side / Node.js\n }\n\n const jsonString = JSON.stringify(data, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n /**\n * Obtiene el historial público de versiones del SDK (Para Leidenfrost.io)\n * Ruta: GET /releases/sdk\n */\n public async listSDkReleases(channel?: SDKChannel): Promise<ApiResponse<SDKRecord[]>> {\n const endpoint = channel ? `/operational/sdks?channel=${channel}` : \"/operational/sdks\";\n return this.http.get<SDKRecord[]>(endpoint);\n }\n\n /**\n * Publicar nueva versión del SDK (Exclusivo Messiah / CI/CD)\n * Ruta: POST /releases/sdk\n */\n public async publishSDKRelease(payload: PublishSDKPayload): Promise<ApiResponse<SDKRecord>> {\n return this.http.post<SDKRecord>(\"/operational/sdks\", payload);\n }\n\n /**\n * Elimina un registro de version del SDK (Para Leidenfrost.io)\n * Ruta: GET /releases/sdk\n */\n public async deleteSDKReleases(id?: String): Promise<ApiResponse<SDKRecord>> {\n return this.http.delete<SDKRecord>(`/operational/sdks?id=${id}`);\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","AuthModule","httpClient","email","password","response","data","refreshToken","OperationalModule","httpClient","payload","tenantId","appId","response","fileName","data","filename","jsonString","blob","url","link","channel","endpoint","id","Leidenfrost","_Leidenfrost","config","HttpClient","AuthModule","OperationalModule","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"],"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"]}
package/dist/index.d.cts CHANGED
@@ -31,209 +31,58 @@ declare class HttpClient {
31
31
  delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
32
32
  }
33
33
 
34
- interface UserRecord {
35
- id: string;
34
+ interface User {
35
+ id?: string;
36
+ tenant_id?: string;
36
37
  email: string;
38
+ password?: string;
37
39
  name: string;
38
40
  last_name: string;
39
41
  telephone?: string;
40
- role: "messiah" | "client" | "admin" | "customer";
42
+ role?: "messiah" | "client" | "admin" | "customer";
41
43
  membership?: {
42
44
  name: string;
43
45
  level: number;
44
46
  points: number;
45
47
  coupons: unknown[];
46
48
  };
47
- enabled: boolean;
49
+ enabled?: boolean;
48
50
  created_at?: unknown;
51
+ update_at?: unknown;
49
52
  }
50
- interface UserSessionData {
51
- user: UserRecord;
53
+ interface Session {
54
+ user: User;
52
55
  authentication_token: string;
53
56
  refresh_token: string;
54
57
  }
55
- interface CreateUserPayload {
56
- email: string;
57
- password: string;
58
- name: string;
59
- last_name: string;
60
- telephone?: string;
61
- [key: string]: unknown;
62
- }
63
- declare class AuthModule {
64
- private http;
65
- constructor(httpClient: HttpClient);
66
- /**
67
- * Iniciar Sesión Messiah (Etapa 2: Login)
68
- * Ruta: POST /user/messiah/session
69
- */
70
- loginMessiah(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
71
- /**
72
- * Crear usuario Client/Tenant (Etapa 1: Registro)
73
- * Ruta: POST /user/client
74
- */
75
- registerClient(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
76
- /**
77
- * Iniciar Sesión Client (Etapa 2: Login)
78
- * Ruta: POST /user/client/session/
79
- */
80
- loginClient(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
81
- /**
82
- * Crear usuario Admin (Etapa 1: Registro)
83
- * Ruta: POST /user/admin
84
- */
85
- registerAdmin(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
86
- /**
87
- * Iniciar Sesión Admin (Etapa 2: Login)
88
- * Ruta: POST /user/admin/session/
89
- */
90
- loginAdmin(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
91
- /**
92
- * Crear usuario Customer (Etapa 1: Registro)
93
- * Ruta: POST /user/costumer
94
- */
95
- registerCustomer(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
96
- /**
97
- * Iniciar Sesión Customer (Etapa 2: Login)
98
- * Ruta: POST /user/costumer/session
99
- */
100
- loginCustomer(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
101
- /**
102
- * Renovar el token de acceso expirado mediante el Refresh Token
103
- * Ruta: POST /user/session/refresh
104
- */
105
- refreshSession(refreshToken: string): Promise<ApiResponse<UserSessionData>>;
106
- /**
107
- * Cierra la sesión en el SDK
108
- */
109
- logout(): void;
110
- }
111
-
112
- type AppPlatform = "web" | "ios" | "android" | "pos";
113
- type SDKChannel = "alpha" | "beta" | "stable";
114
- interface AppRecord {
115
- id: string;
116
- app_id: string;
117
- tenant_id: string;
118
- name: string;
119
- description: string | null;
120
- platform: AppPlatform;
121
- enabled: boolean;
122
- created_at?: unknown;
123
- updated_at?: unknown;
124
- }
125
- interface CreateAppPayload {
126
- name: string;
127
- tenant_id: string;
128
- description?: string;
129
- platform?: AppPlatform;
130
- }
131
- interface CreateServiceAccountPayload {
132
- client_email: string;
133
- app_id: string;
134
- allowed_scopes?: string[];
135
- }
136
- interface ServiceAccountCredentials {
137
- type: "service_account";
138
- client_id: string;
139
- client_email: string;
140
- app_id: string;
141
- tenant_id: string;
142
- private_key_id: string;
143
- private_key: string;
144
- scopes: string[];
145
- }
146
- interface SDKRecord {
147
- release_id: string;
148
- name: string;
149
- description: string;
150
- channel: SDKChannel;
151
- version: string;
152
- min_node_version: string;
153
- changelog: string[];
154
- download_url: string;
155
- public: boolean;
156
- enabled: boolean;
157
- created_at: string;
158
- }
159
- interface PublishSDKPayload {
160
- version: string;
161
- channel?: SDKChannel;
162
- changelog?: string[];
163
- download_url: string;
164
- public: boolean;
165
- min_node_version?: string;
166
- }
167
- declare class OperationalModule {
58
+ declare class UserModule {
168
59
  private http;
169
60
  constructor(httpClient: HttpClient);
170
61
  /**
171
- * Registrar una nueva Aplicación vinculada a un Tenant
172
- * Ruta: POST /operational/apps
173
- */
174
- createApp(payload: CreateAppPayload): Promise<ApiResponse<AppRecord>>;
175
- /**
176
- * Obtener todas las Aplicaciones de un Tenant
177
- * Ruta: GET /operational/apps?tenant_id=xxx
178
- */
179
- listAppsByTenant(tenantId: string): Promise<ApiResponse<AppRecord[]>>;
180
- /**
181
- * Obtener detalle de una Aplicación por su app_id o id de documento
182
- * Ruta: GET /operational/apps/:appId
62
+ * Module: Session
63
+ * Ruta: /user/session
183
64
  */
184
- getAppDetail(appId: string): Promise<ApiResponse<AppRecord>>;
65
+ getSession(id: string): Promise<ApiResponse<Session>>;
66
+ postSession(email: string, password: string): Promise<ApiResponse<Session>>;
67
+ patchSession(refreshToken: string): Promise<ApiResponse<Session>>;
68
+ deleteSession(refreshToken: string): Promise<ApiResponse<null>>;
185
69
  /**
186
- * Actualizar datos de una Aplicación
187
- * Ruta: PUT /operational/apps/:appId
70
+ * Module: USER
71
+ * Ruta: /user
188
72
  */
189
- updateApp(appId: string, payload: Partial<Omit<AppRecord, "id" | "app_id" | "tenant_id" | "created_at">>): Promise<ApiResponse<AppRecord>>;
190
- /**
191
- * Deshabilitar / Eliminar una Aplicación
192
- * Ruta: DELETE /operational/apps/:appId
193
- */
194
- deleteApp(appId: string): Promise<ApiResponse<{
195
- id: string;
196
- deleted: boolean;
197
- }>>;
198
- /**
199
- * Genera una Service Account y retorna sus credenciales (incluyendo PKCS#8 Private Key)
200
- * Ruta: POST /operational/apps/service-account
201
- */
202
- createServiceAccount(payload: CreateServiceAccountPayload): Promise<ApiResponse<ServiceAccountCredentials>>;
203
- /**
204
- * Genera una Service Account e inicie la descarga automática del archivo JSON de credenciales en el navegador
205
- * Ruta: POST /operational/apps/service-account
206
- */
207
- createServiceAccountAndDownload(payload: CreateServiceAccountPayload): Promise<ApiResponse<ServiceAccountCredentials>>;
208
- /**
209
- * Utilería del cliente para forzar la descarga del .json en el navegador (Estilo Firebase / GCP)
210
- */
211
- private triggerJsonDownload;
212
- /**
213
- * Obtiene el historial público de versiones del SDK (Para Leidenfrost.io)
214
- * Ruta: GET /releases/sdk
215
- */
216
- listSDkReleases(channel?: SDKChannel): Promise<ApiResponse<SDKRecord[]>>;
217
- /**
218
- * Publicar nueva versión del SDK (Exclusivo Messiah / CI/CD)
219
- * Ruta: POST /releases/sdk
220
- */
221
- publishSDKRelease(payload: PublishSDKPayload): Promise<ApiResponse<SDKRecord>>;
222
- /**
223
- * Elimina un registro de version del SDK (Para Leidenfrost.io)
224
- * Ruta: GET /releases/sdk
225
- */
226
- deleteSDKReleases(id?: String): Promise<ApiResponse<SDKRecord>>;
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>>;
227
77
  }
228
78
 
229
79
  declare class Leidenfrost {
230
80
  private httpClient;
231
- auth: AuthModule;
232
- operational: OperationalModule;
81
+ user: UserModule;
233
82
  constructor(config: HttpClientConfig);
234
83
  static initializeApp(config: HttpClientConfig): Leidenfrost;
235
84
  setUserSessionToken(token: string | null): void;
236
85
  getUserSessionToken(): string | null;
237
86
  }
238
87
 
239
- export { type ApiResponse, type AppPlatform, type AppRecord, type CreateAppPayload, type CreateServiceAccountPayload, type CreateUserPayload, type HttpClientConfig, Leidenfrost, type PublishSDKPayload, type SDKChannel, type SDKRecord, type ServiceAccountCredentials, type UserRecord, type UserSessionData, Leidenfrost as default };
88
+ export { type ApiResponse, type HttpClientConfig, Leidenfrost, type Session, type User, Leidenfrost as default };
package/dist/index.d.ts CHANGED
@@ -31,209 +31,58 @@ declare class HttpClient {
31
31
  delete<T = unknown>(endpoint: string, options?: HttpRequestOptions): Promise<ApiResponse<T>>;
32
32
  }
33
33
 
34
- interface UserRecord {
35
- id: string;
34
+ interface User {
35
+ id?: string;
36
+ tenant_id?: string;
36
37
  email: string;
38
+ password?: string;
37
39
  name: string;
38
40
  last_name: string;
39
41
  telephone?: string;
40
- role: "messiah" | "client" | "admin" | "customer";
42
+ role?: "messiah" | "client" | "admin" | "customer";
41
43
  membership?: {
42
44
  name: string;
43
45
  level: number;
44
46
  points: number;
45
47
  coupons: unknown[];
46
48
  };
47
- enabled: boolean;
49
+ enabled?: boolean;
48
50
  created_at?: unknown;
51
+ update_at?: unknown;
49
52
  }
50
- interface UserSessionData {
51
- user: UserRecord;
53
+ interface Session {
54
+ user: User;
52
55
  authentication_token: string;
53
56
  refresh_token: string;
54
57
  }
55
- interface CreateUserPayload {
56
- email: string;
57
- password: string;
58
- name: string;
59
- last_name: string;
60
- telephone?: string;
61
- [key: string]: unknown;
62
- }
63
- declare class AuthModule {
64
- private http;
65
- constructor(httpClient: HttpClient);
66
- /**
67
- * Iniciar Sesión Messiah (Etapa 2: Login)
68
- * Ruta: POST /user/messiah/session
69
- */
70
- loginMessiah(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
71
- /**
72
- * Crear usuario Client/Tenant (Etapa 1: Registro)
73
- * Ruta: POST /user/client
74
- */
75
- registerClient(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
76
- /**
77
- * Iniciar Sesión Client (Etapa 2: Login)
78
- * Ruta: POST /user/client/session/
79
- */
80
- loginClient(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
81
- /**
82
- * Crear usuario Admin (Etapa 1: Registro)
83
- * Ruta: POST /user/admin
84
- */
85
- registerAdmin(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
86
- /**
87
- * Iniciar Sesión Admin (Etapa 2: Login)
88
- * Ruta: POST /user/admin/session/
89
- */
90
- loginAdmin(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
91
- /**
92
- * Crear usuario Customer (Etapa 1: Registro)
93
- * Ruta: POST /user/costumer
94
- */
95
- registerCustomer(data: CreateUserPayload): Promise<ApiResponse<UserRecord>>;
96
- /**
97
- * Iniciar Sesión Customer (Etapa 2: Login)
98
- * Ruta: POST /user/costumer/session
99
- */
100
- loginCustomer(email: string, password: string): Promise<ApiResponse<UserSessionData>>;
101
- /**
102
- * Renovar el token de acceso expirado mediante el Refresh Token
103
- * Ruta: POST /user/session/refresh
104
- */
105
- refreshSession(refreshToken: string): Promise<ApiResponse<UserSessionData>>;
106
- /**
107
- * Cierra la sesión en el SDK
108
- */
109
- logout(): void;
110
- }
111
-
112
- type AppPlatform = "web" | "ios" | "android" | "pos";
113
- type SDKChannel = "alpha" | "beta" | "stable";
114
- interface AppRecord {
115
- id: string;
116
- app_id: string;
117
- tenant_id: string;
118
- name: string;
119
- description: string | null;
120
- platform: AppPlatform;
121
- enabled: boolean;
122
- created_at?: unknown;
123
- updated_at?: unknown;
124
- }
125
- interface CreateAppPayload {
126
- name: string;
127
- tenant_id: string;
128
- description?: string;
129
- platform?: AppPlatform;
130
- }
131
- interface CreateServiceAccountPayload {
132
- client_email: string;
133
- app_id: string;
134
- allowed_scopes?: string[];
135
- }
136
- interface ServiceAccountCredentials {
137
- type: "service_account";
138
- client_id: string;
139
- client_email: string;
140
- app_id: string;
141
- tenant_id: string;
142
- private_key_id: string;
143
- private_key: string;
144
- scopes: string[];
145
- }
146
- interface SDKRecord {
147
- release_id: string;
148
- name: string;
149
- description: string;
150
- channel: SDKChannel;
151
- version: string;
152
- min_node_version: string;
153
- changelog: string[];
154
- download_url: string;
155
- public: boolean;
156
- enabled: boolean;
157
- created_at: string;
158
- }
159
- interface PublishSDKPayload {
160
- version: string;
161
- channel?: SDKChannel;
162
- changelog?: string[];
163
- download_url: string;
164
- public: boolean;
165
- min_node_version?: string;
166
- }
167
- declare class OperationalModule {
58
+ declare class UserModule {
168
59
  private http;
169
60
  constructor(httpClient: HttpClient);
170
61
  /**
171
- * Registrar una nueva Aplicación vinculada a un Tenant
172
- * Ruta: POST /operational/apps
173
- */
174
- createApp(payload: CreateAppPayload): Promise<ApiResponse<AppRecord>>;
175
- /**
176
- * Obtener todas las Aplicaciones de un Tenant
177
- * Ruta: GET /operational/apps?tenant_id=xxx
178
- */
179
- listAppsByTenant(tenantId: string): Promise<ApiResponse<AppRecord[]>>;
180
- /**
181
- * Obtener detalle de una Aplicación por su app_id o id de documento
182
- * Ruta: GET /operational/apps/:appId
62
+ * Module: Session
63
+ * Ruta: /user/session
183
64
  */
184
- getAppDetail(appId: string): Promise<ApiResponse<AppRecord>>;
65
+ getSession(id: string): Promise<ApiResponse<Session>>;
66
+ postSession(email: string, password: string): Promise<ApiResponse<Session>>;
67
+ patchSession(refreshToken: string): Promise<ApiResponse<Session>>;
68
+ deleteSession(refreshToken: string): Promise<ApiResponse<null>>;
185
69
  /**
186
- * Actualizar datos de una Aplicación
187
- * Ruta: PUT /operational/apps/:appId
70
+ * Module: USER
71
+ * Ruta: /user
188
72
  */
189
- updateApp(appId: string, payload: Partial<Omit<AppRecord, "id" | "app_id" | "tenant_id" | "created_at">>): Promise<ApiResponse<AppRecord>>;
190
- /**
191
- * Deshabilitar / Eliminar una Aplicación
192
- * Ruta: DELETE /operational/apps/:appId
193
- */
194
- deleteApp(appId: string): Promise<ApiResponse<{
195
- id: string;
196
- deleted: boolean;
197
- }>>;
198
- /**
199
- * Genera una Service Account y retorna sus credenciales (incluyendo PKCS#8 Private Key)
200
- * Ruta: POST /operational/apps/service-account
201
- */
202
- createServiceAccount(payload: CreateServiceAccountPayload): Promise<ApiResponse<ServiceAccountCredentials>>;
203
- /**
204
- * Genera una Service Account e inicie la descarga automática del archivo JSON de credenciales en el navegador
205
- * Ruta: POST /operational/apps/service-account
206
- */
207
- createServiceAccountAndDownload(payload: CreateServiceAccountPayload): Promise<ApiResponse<ServiceAccountCredentials>>;
208
- /**
209
- * Utilería del cliente para forzar la descarga del .json en el navegador (Estilo Firebase / GCP)
210
- */
211
- private triggerJsonDownload;
212
- /**
213
- * Obtiene el historial público de versiones del SDK (Para Leidenfrost.io)
214
- * Ruta: GET /releases/sdk
215
- */
216
- listSDkReleases(channel?: SDKChannel): Promise<ApiResponse<SDKRecord[]>>;
217
- /**
218
- * Publicar nueva versión del SDK (Exclusivo Messiah / CI/CD)
219
- * Ruta: POST /releases/sdk
220
- */
221
- publishSDKRelease(payload: PublishSDKPayload): Promise<ApiResponse<SDKRecord>>;
222
- /**
223
- * Elimina un registro de version del SDK (Para Leidenfrost.io)
224
- * Ruta: GET /releases/sdk
225
- */
226
- deleteSDKReleases(id?: String): Promise<ApiResponse<SDKRecord>>;
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>>;
227
77
  }
228
78
 
229
79
  declare class Leidenfrost {
230
80
  private httpClient;
231
- auth: AuthModule;
232
- operational: OperationalModule;
81
+ user: UserModule;
233
82
  constructor(config: HttpClientConfig);
234
83
  static initializeApp(config: HttpClientConfig): Leidenfrost;
235
84
  setUserSessionToken(token: string | null): void;
236
85
  getUserSessionToken(): string | null;
237
86
  }
238
87
 
239
- export { type ApiResponse, type AppPlatform, type AppRecord, type CreateAppPayload, type CreateServiceAccountPayload, type CreateUserPayload, type HttpClientConfig, Leidenfrost, type PublishSDKPayload, type SDKChannel, type SDKRecord, type ServiceAccountCredentials, type UserRecord, type UserSessionData, Leidenfrost as default };
88
+ 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 T,importPKCS8 as K}from"jose";var u=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 K(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 T({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 a=s[o];a!==void 0&&(i+=String.fromCharCode(a))}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 u(t)}setUserSessionToken(e){this.userSessionToken=e}getUserSessionToken(){return this.userSessionToken}async request(e,t={}){let{body:s,headers:i,customScopes:o,method:a="GET",...w}=t,b=await this.signer.generateM2MToken(o),p=new Headers;p.set("Content-Type","application/json"),p.set("Accept","application/json"),p.set("Authorization",`Bearer ${b}`),this.userSessionToken&&p.set("X-User-Session",this.userSessionToken),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 l;if(s!=null)if(typeof s=="object"&&!(s instanceof FormData)){let r=s.data?s:{data:d.encode(s)};l=JSON.stringify(r)}else l=String(s);let A=e.startsWith("/")?e:`/${e}`,k=`${this.apiUrl}${A}`,f={...w,method:a,headers:p};l!==void 0&&(f.body=l);let C=new Request(k,f);try{let n=await fetch(C),r=null,S=n.headers.get("content-type");if(S&&S.includes("application/json")?r=await n.json():r=await n.text(),!n.ok){let R=r&&typeof r=="object"?r:{},P={success:!1,status:n.status,message:typeof R.message=="string"?R.message:`Error HTTP ${n.status}: ${n.statusText}`,data:null};return Promise.reject(P)}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 loginMessiah(e,t){let s=await this.http.post("/user/messiah/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerClient(e){return this.http.post("/user/client",e)}async loginClient(e,t){let s=await this.http.post("/user/client/session/",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerAdmin(e){return this.http.post("/user/admin",e)}async loginAdmin(e,t){let s=await this.http.post("/user/admin/session/",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async registerCustomer(e){return this.http.post("/user/costumer",e)}async loginCustomer(e,t){let s=await this.http.post("/user/costumer/session",{email:e,password:t});return s.success&&s.data?.authentication_token&&this.http.setUserSessionToken(s.data.authentication_token),s}async refreshSession(e){let t=await this.http.post("/user/session/refresh",{refresh_token:e});return t.success&&t.data?.authentication_token&&this.http.setUserSessionToken(t.data.authentication_token),t}logout(){this.http.setUserSessionToken(null)}};var y=class{http;constructor(e){this.http=e}async createApp(e){return this.http.post("/operational/apps",e)}async listAppsByTenant(e){return this.http.get(`/operational/apps?tenant_id=${encodeURIComponent(e)}`)}async getAppDetail(e){return this.http.get(`/operational/apps?app_id=${e}`)}async updateApp(e,t){return this.http.put(`/operational/apps?app_id=${e}`,t)}async deleteApp(e){return this.http.delete(`/operational/apps?app_id=${e}`)}async createServiceAccount(e){return this.http.post("/operational/apps/service-account",e)}async createServiceAccountAndDownload(e){let t=await this.createServiceAccount(e);if(t.success&&t.data){let s=`${t.data.client_id||"service-account"}.json`;this.triggerJsonDownload(t.data,s)}return t}triggerJsonDownload(e,t){if(typeof window>"u"||typeof document>"u")return;let s=JSON.stringify(e,null,2),i=new Blob([s],{type:"application/json"}),o=URL.createObjectURL(i),a=document.createElement("a");a.href=o,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(o)}async listSDkReleases(e){let t=e?`/operational/sdks?channel=${e}`:"/operational/sdks";return this.http.get(t)}async publishSDKRelease(e){return this.http.post("/operational/sdks",e)}async deleteSDKReleases(e){return this.http.delete(`/operational/sdks?id=${e}`)}};var m=class c{httpClient;auth;operational;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.auth=new g(this.httpClient),this.operational=new y(this.httpClient)}static initializeApp(e){return new c(e)}setUserSessionToken(e){this.httpClient.setUserSessionToken(e)}getUserSessionToken(){return this.httpClient.getUserSessionToken()}},$=m;export{m as Leidenfrost,$ as default};
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};
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/AuthModule.ts","../src/modules/OperationalModule.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-User-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}","\nimport type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport interface UserRecord {\n id: string;\n email: 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}\n\nexport interface UserSessionData {\n user: UserRecord;\n authentication_token: string;\n refresh_token: string;\n}\n\nexport interface CreateUserPayload {\n email: string;\n password: string;\n name: string;\n last_name: string;\n telephone?: string;\n [key: string]: unknown;\n}\n\nexport class AuthModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n // ==========================================\n // 1. MESSIAH (SuperAdmin Platform)\n // ==========================================\n /**\n * Iniciar Sesión Messiah (Etapa 2: Login)\n * Ruta: POST /user/messiah/session\n */\n public async loginMessiah(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/messiah/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 // ==========================================\n // 2. CLIENT (Tenant B2B Owner)\n // ==========================================\n\n /**\n * Crear usuario Client/Tenant (Etapa 1: Registro)\n * Ruta: POST /user/client\n */\n public async registerClient(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/client\", data);\n }\n\n /**\n * Iniciar Sesión Client (Etapa 2: Login)\n * Ruta: POST /user/client/session/\n */\n public async loginClient(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/client/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 // ==========================================\n // 3. ADMIN (Personal Operativo del Tenant)\n // ==========================================\n\n /**\n * Crear usuario Admin (Etapa 1: Registro)\n * Ruta: POST /user/admin\n */\n public async registerAdmin(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/admin\", data);\n }\n\n /**\n * Iniciar Sesión Admin (Etapa 2: Login)\n * Ruta: POST /user/admin/session/\n */\n public async loginAdmin(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/admin/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 // ==========================================\n // 4. CUSTOMER (Comprador Final B2C)\n // ==========================================\n\n /**\n * Crear usuario Customer (Etapa 1: Registro)\n * Ruta: POST /user/costumer\n */\n public async registerCustomer(data: CreateUserPayload): Promise<ApiResponse<UserRecord>> {\n return this.http.post<UserRecord>(\"/user/costumer\", data);\n }\n\n /**\n * Iniciar Sesión Customer (Etapa 2: Login)\n * Ruta: POST /user/costumer/session\n */\n public async loginCustomer(email: string, password: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/costumer/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 // ==========================================\n // GESTIÓN DE SESIÓN Y REFRESH TOKEN\n // ==========================================\n\n /**\n * Renovar el token de acceso expirado mediante el Refresh Token\n * Ruta: POST /user/session/refresh\n */\n public async refreshSession(refreshToken: string): Promise<ApiResponse<UserSessionData>> {\n const response = await this.http.post<UserSessionData>(\"/user/session/refresh\", { 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 /**\n * Cierra la sesión en el SDK\n */\n public logout(): void {\n this.http.setUserSessionToken(null);\n }\n}","import type { HttpClient, ApiResponse } from \"../core/HttpClient.js\";\n\nexport type AppPlatform = \"web\" | \"ios\" | \"android\" | \"pos\";\nexport type SDKChannel = \"alpha\" | \"beta\" | \"stable\";\n\nexport interface AppRecord {\n id: string;\n app_id: string;\n tenant_id: string;\n name: string;\n description: string | null;\n platform: AppPlatform;\n enabled: boolean;\n created_at?: unknown;\n updated_at?: unknown;\n}\n\nexport interface CreateAppPayload {\n name: string;\n tenant_id: string;\n description?: string;\n platform?: AppPlatform;\n}\n\nexport interface CreateServiceAccountPayload {\n client_email: string;\n app_id: string;\n allowed_scopes?: string[];\n}\n\nexport interface ServiceAccountCredentials {\n type: \"service_account\";\n client_id: string;\n client_email: string;\n app_id: string;\n tenant_id: string;\n private_key_id: string;\n private_key: string;\n scopes: string[];\n}\n\n\nexport interface SDKRecord {\n release_id: string;\n name: string;\n description: string;\n channel: SDKChannel;\n version: string;\n min_node_version: string;\n changelog: string[];\n download_url: string;\n public: boolean;\n enabled: boolean;\n created_at: string;\n}\n\nexport interface PublishSDKPayload {\n version: string;\n channel?: SDKChannel;\n changelog?: string[];\n download_url: string;\n public: boolean;\n min_node_version?: string;\n}\n\n\nexport class OperationalModule {\n private http: HttpClient;\n\n constructor(httpClient: HttpClient) {\n this.http = httpClient;\n }\n\n // ==========================================\n // CRUD DE APLICACIONES (POST, GET, PUT, DELETE)\n // Ruta Base: /operational/apps\n // ==========================================\n\n /**\n * Registrar una nueva Aplicación vinculada a un Tenant\n * Ruta: POST /operational/apps\n */\n public async createApp(payload: CreateAppPayload): Promise<ApiResponse<AppRecord>> {\n return this.http.post<AppRecord>(\"/operational/apps\", payload);\n }\n\n /**\n * Obtener todas las Aplicaciones de un Tenant\n * Ruta: GET /operational/apps?tenant_id=xxx\n */\n public async listAppsByTenant(tenantId: string): Promise<ApiResponse<AppRecord[]>> {\n return this.http.get<AppRecord[]>(`/operational/apps?tenant_id=${encodeURIComponent(tenantId)}`);\n }\n\n /**\n * Obtener detalle de una Aplicación por su app_id o id de documento\n * Ruta: GET /operational/apps/:appId\n */\n public async getAppDetail(appId: string): Promise<ApiResponse<AppRecord>> {\n return this.http.get<AppRecord>(`/operational/apps?app_id=${appId}`);\n }\n\n /**\n * Actualizar datos de una Aplicación\n * Ruta: PUT /operational/apps/:appId\n */\n public async updateApp(\n appId: string,\n payload: Partial<Omit<AppRecord, \"id\" | \"app_id\" | \"tenant_id\" | \"created_at\">>\n ): Promise<ApiResponse<AppRecord>> {\n return this.http.put<AppRecord>(`/operational/apps?app_id=${appId}`, payload);\n }\n\n /**\n * Deshabilitar / Eliminar una Aplicación\n * Ruta: DELETE /operational/apps/:appId\n */\n public async deleteApp(appId: string): Promise<ApiResponse<{ id: string; deleted: boolean }>> {\n return this.http.delete<{ id: string; deleted: boolean }>(`/operational/apps?app_id=${appId}`);\n }\n\n// ==========================================\n // SERVICE ACCOUNTS (/operational/apps/service-account)\n // ==========================================\n\n /**\n * Genera una Service Account y retorna sus credenciales (incluyendo PKCS#8 Private Key)\n * Ruta: POST /operational/apps/service-account\n */\n public async createServiceAccount(\n payload: CreateServiceAccountPayload\n ): Promise<ApiResponse<ServiceAccountCredentials>> {\n return this.http.post<ServiceAccountCredentials>(\"/operational/apps/service-account\", payload);\n }\n\n /**\n * Genera una Service Account e inicie la descarga automática del archivo JSON de credenciales en el navegador\n * Ruta: POST /operational/apps/service-account\n */\n public async createServiceAccountAndDownload(\n payload: CreateServiceAccountPayload\n ): Promise<ApiResponse<ServiceAccountCredentials>> {\n const response = await this.createServiceAccount(payload);\n\n if (response.success && response.data) {\n const fileName = `${response.data.client_id || \"service-account\"}.json`;\n this.triggerJsonDownload(response.data, fileName);\n }\n\n return response;\n }\n\n /**\n * Utilería del cliente para forzar la descarga del .json en el navegador (Estilo Firebase / GCP)\n */\n private triggerJsonDownload(data: object, filename: string): void {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return; // Prevenir ejecución en Server-Side / Node.js\n }\n\n const jsonString = JSON.stringify(data, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n }\n\n /**\n * Obtiene el historial público de versiones del SDK (Para Leidenfrost.io)\n * Ruta: GET /releases/sdk\n */\n public async listSDkReleases(channel?: SDKChannel): Promise<ApiResponse<SDKRecord[]>> {\n const endpoint = channel ? `/operational/sdks?channel=${channel}` : \"/operational/sdks\";\n return this.http.get<SDKRecord[]>(endpoint);\n }\n\n /**\n * Publicar nueva versión del SDK (Exclusivo Messiah / CI/CD)\n * Ruta: POST /releases/sdk\n */\n public async publishSDKRelease(payload: PublishSDKPayload): Promise<ApiResponse<SDKRecord>> {\n return this.http.post<SDKRecord>(\"/operational/sdks\", payload);\n }\n\n /**\n * Elimina un registro de version del SDK (Para Leidenfrost.io)\n * Ruta: GET /releases/sdk\n */\n public async deleteSDKReleases(id?: String): Promise<ApiResponse<SDKRecord>> {\n return this.http.delete<SDKRecord>(`/operational/sdks?id=${id}`);\n }\n}","import { HttpClient } from \"./core/HttpClient.js\";\nimport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\nimport { AuthModule } from \"./modules/AuthModule.js\";\nimport { OperationalModule } from \"./modules/OperationalModule.js\";\n\nexport type { HttpClientConfig, ApiResponse } from \"./core/HttpClient.js\";\nexport type { UserRecord, UserSessionData, CreateUserPayload } from \"./modules/AuthModule.js\";\nexport type {\n AppRecord,\n CreateAppPayload,\n AppPlatform,\n CreateServiceAccountPayload,\n ServiceAccountCredentials,\n SDKRecord,\n PublishSDKPayload,\n SDKChannel\n} from \"./modules/OperationalModule.js\";\n\nexport class Leidenfrost {\n private httpClient: HttpClient;\n public auth: AuthModule;\n public operational: OperationalModule;\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.auth = new AuthModule(this.httpClient);\n this.operational = new OperationalModule(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","AuthModule","httpClient","email","password","response","data","refreshToken","OperationalModule","httpClient","payload","tenantId","appId","response","fileName","data","filename","jsonString","blob","url","link","channel","endpoint","id","Leidenfrost","_Leidenfrost","config","HttpClient","AuthModule","OperationalModule","token","index_default"]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leidenfrost/sdk",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.2",
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",
@@ -9,15 +9,15 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/index.d.ts",
12
- "import": "./dist/index.mjs",
13
- "require": "./dist/index.js"
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
14
  }
15
15
  },
16
16
  "files": [
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "tsup",
20
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
21
21
  "dev": "tsup --watch",
22
22
  "prepublishOnly": "npm run build"
23
23
  },