foundation-sdk 0.2.0 → 0.2.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,2 +1,2 @@
1
- "use strict";var D=Object.create;var P=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var M=(e,t)=>{for(var i in t)P(e,i,{get:t[i],enumerable:!0})},A=(e,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of j(t))!H.call(e,r)&&r!==i&&P(e,r,{get:()=>t[r],enumerable:!(o=B(t,r))||o.enumerable});return e};var h=(e,t,i)=>(i=e!=null?D(L(e)):{},A(t||!e||!e.__esModule?P(i,"default",{value:e,enumerable:!0}):i,e)),G=e=>A(P({},"__esModule",{value:!0}),e);var Y={};M(Y,{createFoundation:()=>b});module.exports=G(Y);function J(e){return e?.response!==void 0?e.response:e?.data!==void 0?e.data:e}function N(e,t){let i=t?.error;if(i){let r=i.message||"Unknown error",n=i.details;if(n?.length){let s=n.map(a=>a.field?`${a.field}: ${a.message}`:a.message).join(", ");r=r?`${r} ${s}`:s}return Object.assign(new Error(r),{code:i.code,type:i.code,details:n,status:e})}let o=t?.data?.message||t?.message;return o?Object.assign(new Error(o),{status:e}):Object.assign(new Error(`HTTP ${e}`),{status:e})}function I(e){function t(r){return{"X-Foundation-Mvp-Application-Id":e.appId,"X-Foundation-Mvp-Tenant-Id":e.tenantId,"X-Foundation-Mvp-Application-Version":e.version,"Content-Type":"application/json",Authorization:`Bearer ${r}`}}async function i(r,n,s,a={}){let u=await e.getToken(),c=t(u),g=`${r}${n}`;if(a.params){let p=new URLSearchParams;for(let[w,y]of Object.entries(a.params))y!=null&&p.set(w,String(y));let v=p.toString();v&&(g+=`?${v}`)}let l={method:s,headers:c};a.body!==void 0&&(l.body=JSON.stringify(a.body));let f=await fetch(g,l);if(!f.ok){let p={};try{p=await f.json()}catch{}throw N(f.status,p)}if(f.status===204)return null;let S=await f.json();return J(S)}async function o(r,n={}){return fetch(r,n)}return{request:i,rawFetch:o,headers:t}}async function T(e){switch(e.provider){case"auth0":{if(!e.auth0)throw new Error("Auth0 config required");let{createAuth0Client:t}=await import("@auth0/auth0-spa-js"),i=await t({domain:e.auth0.domain,clientId:e.auth0.clientId,authorizationParams:{audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email",redirect_uri:window.location.origin},useRefreshTokens:!0,cacheLocation:"localstorage"}),o=e.auth0.domain,r=e.auth0.clientId;return{login:n=>i.loginWithRedirect(n),logout:n=>i.logout({logoutParams:{returnTo:window.location.origin},...n}),getUser:async()=>{let n=await i.getUser();if(n)return{id:n.sub||"",email:n.email||"",name:n.name,picture:n.picture}},getTokenSilently:n=>i.getTokenSilently(n),isAuthenticated:()=>i.isAuthenticated(),async signIn(n,s){let a=await fetch(`https://${o}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"password",client_id:r,username:n,password:s,audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email"})});if(!a.ok){let u=await a.json().catch(()=>({}));throw new Error(u.error_description||u.message||"Sign in failed")}},async signUp(n,s,a){let u=await fetch(`https://${o}/dbconnections/signup`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:r,email:n,password:s,connection:"Username-Password-Authentication",...a})});if(!u.ok){let c=await u.json().catch(()=>({}));throw new Error(c.description||c.message||"Sign up failed")}},async forgotPassword(n){let s=await fetch(`https://${o}/dbconnections/change_password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:r,email:n,connection:"Username-Password-Authentication"})});if(!s.ok){let a=await s.json().catch(()=>({}));throw new Error(a.error_description||a.message||"Password reset request failed")}},async resetPassword(n,s){throw new Error("Auth0 password reset is completed via the email link, not a code")}}}case"cognito":{if(!e.cognito)throw new Error("Cognito config required");let{fetchAuthSession:t,signInWithRedirect:i,signOut:o,getCurrentUser:r}=await import("aws-amplify/auth"),{Amplify:n}=await import("aws-amplify");return n.configure({Auth:{Cognito:{userPoolId:e.cognito.userPoolId,userPoolClientId:e.cognito.clientId,loginWith:{oauth:{domain:e.cognito.domain.replace("https://",""),scopes:(e.cognito.scope||"openid profile email").split(" "),redirectSignIn:[window.location.origin],redirectSignOut:[window.location.origin],responseType:"code"}}}}}),{login:async()=>{await i()},logout:async()=>{await o()},getUser:async()=>{try{let s=await r();return{id:s.userId,email:s.signInDetails?.loginId||"",name:s.username}}catch{return}},getTokenSilently:async()=>{let a=(await t()).tokens?.accessToken?.toString();if(!a)throw new Error("No token available");return a},isAuthenticated:async()=>{try{return await r(),!0}catch{return!1}},async signIn(s,a){let{signIn:u}=await import("aws-amplify/auth");await u({username:s,password:a})},async signUp(s,a,u){let{signUp:c}=await import("aws-amplify/auth");await c({username:s,password:a,options:{userAttributes:{email:s,...u}}})},async forgotPassword(s){let{resetPassword:a}=await import("aws-amplify/auth");await a({username:s})},async resetPassword(s,a){let{confirmResetPassword:u}=await import("aws-amplify/auth");await u({username:"",confirmationCode:s,newPassword:a})}}}case"none":return{login:async()=>{},logout:async()=>{},getUser:async()=>{},getTokenSilently:async()=>"none",isAuthenticated:async()=>!0};default:throw new Error(`Unknown auth provider: ${e.provider}`)}}function E(e){let t=null,i=[];function o(){i.forEach(r=>{try{r(t)}catch{}})}return{get user(){return t},get isAuthenticated(){return!!t},async getToken(){return e.getTokenSilently()},async login(r){await e.login(r);let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null,o()},async logout(r){await e.logout(r),t=null,o()},async signIn(r,n){if(!e.signIn)throw new Error("signIn not supported by this auth provider");await e.signIn(r,n);let s=await e.getUser();t=s?{id:s.id,email:s.email,name:s.name,picture:s.picture}:null,o()},async signUp(r,n,s){if(!e.signUp)throw new Error("signUp not supported by this auth provider");await e.signUp(r,n,s)},async forgotPassword(r){if(!e.forgotPassword)throw new Error("forgotPassword not supported by this auth provider");await e.forgotPassword(r)},async resetPassword(r,n){if(!e.resetPassword)throw new Error("resetPassword not supported by this auth provider");await e.resetPassword(r,n)},onChange(r){return i.length>=100?(console.warn("[Foundation SDK] Auth listener limit reached."),()=>{}):(i.push(r),()=>{let n=i.indexOf(r);n>-1&&i.splice(n,1)})},async _initUser(){if(await e.isAuthenticated()){let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null}}}}function C(e){if(!e)throw new Error("Token parsing failed: Missing auth token");try{let[t,i]=e.split("?"),o=t.split(".");if(o.length!==3)throw new Error("Invalid JWT format");let r=atob(o[1]),n=JSON.parse(r);i&&new URLSearchParams(i).forEach((g,l)=>{n[l]=g});let s=n["BaseApplication/apiBaseUrl"];if(!s)throw new Error("Token missing apiBaseUrl");let a=n["BaseApplication/websocketBaseUrl"]||"",u=n["BaseApplication/accountBaseUrl"]||s;return{sub:n.sub||"",apiBaseUrl:s,accountBaseUrl:u,websocketBaseUrl:a,userId:n["BaseApplication/userId"]||"",namespace:n["BaseApplication/namespace"]}}catch(t){if(t instanceof Error&&t.message.startsWith("Token"))throw t;let i=t instanceof Error?t.message:"Failed to parse token";throw new Error(`Token parsing failed: ${i}`)}}async function b(e){let t={Accept:"application/json","Cache-Control":"no-cache"};e.appId&&(t["X-Foundation-Mvp-Application-Id"]=e.appId),e.tenantId&&(t["X-Foundation-Mvp-Tenant-Id"]=e.tenantId);let i=await fetch(e.configUrl,{headers:t});if(!i.ok)throw new Error(`Failed to fetch config: ${i.statusText}`);let o=await i.json(),r=o.data??o,n=r.auth||{provider:"none"},s=e.auth||await T(n),u=E(s);await u._initUser();let c,g;if(e.baseUrl)c=e.baseUrl,g=e.baseUrl;else if(n.apiUrls?.apiBaseUrl)c=n.apiUrls.apiBaseUrl,g=n.apiUrls.accountBaseUrl||c;else{let d=await s.getTokenSilently(),m=C(d);c=m.apiBaseUrl,g=m.accountBaseUrl}let l=e.appId||r.app?.id||r.tenant?.identifier||"",f=e.tenantId||r.tenant?.identifier||"",S=r.app?.version||r.core?.version||"0.0.0",p=I({appId:l,tenantId:f,version:S,getToken:()=>s.getTokenSilently()}),v={};try{v=await p.request(c,"/api/v1/config/init","GET")||{}}catch(d){console.warn("[Foundation SDK] Backend config fetch failed:",d)}let w={...r,...v},y="";try{let d=await s.getTokenSilently();d&&d!=="none"&&(y=C(d).namespace||"")}catch{}let R={get app(){let d=w.app||{};return{id:d.id||l,name:d.name||"",version:d.version||S,environment:d.environment||"",...d}},get features(){return w.features||{}},get plans(){return w.plans||[]},get theme(){let d=w.theme||{};return{colors:d.colors||{},dark:d.dark||{},defaultColorScheme:d.defaultColorScheme}},get connectors(){return w.connectors||{}},get resources(){return w.resources||{}},get auth(){let{provider:d,...m}=n;return{provider:d,...m}},get raw(){return w}},F=X(p,c),q=W(p,c,y),O=z(p,g),$=K(p,c,g,y),_=V(p,c),x=Q(),U=[];return{get ready(){return Promise.resolve()},get isReady(){return!0},auth:u,db:F,files:q,integration:$,account:O,config:R,openapi:_,log:x,on(d,m){return d==="entity.changed"?(U.push(m),()=>{let k=U.indexOf(m);k>-1&&U.splice(k,1)}):()=>{}}}}function X(e,t){return{async list(i,o={}){let{filters:r,limit:n,cursor:s,orderBy:a,orderDir:u}=o,c={...r};return n&&(c.limit=n),s&&(c.next=s),a&&(c.orderBy=a),u&&(c.orderDir=u),e.request(t,`/api/v1/core/${i}`,"GET",{params:c})},async get(i,o){return e.request(t,`/api/v1/core/${i}`,"GET",{params:{id:o}})},async create(i,o){return e.request(t,`/api/v1/core/${i}`,"POST",{body:o})},async update(i,o,r){return e.request(t,`/api/v1/core/${i}`,"PUT",{body:{id:o,...r}})},async save(i,o){try{return await e.request(t,`/api/v1/core/${i}`,"PUT",{body:o})}catch{return e.request(t,`/api/v1/core/${i}`,"POST",{body:o})}},async delete(i,o){await e.request(t,`/api/v1/core/${i}`,"DELETE",{body:{id:o}})}}}function W(e,t,i){return{async initiate(o){return e.request(t,"/api/v1/core/upload","POST",{body:{...o,__namespace:i}})},async upload(o){let r;o.file instanceof ArrayBuffer?r=o.file:r=await o.file.arrayBuffer();let n=await e.request(t,"/api/v1/core/upload","POST",{body:{name:o.name,contentType:o.contentType,contentLength:r.byteLength,sha256:o.sha256,__namespace:i}});if(!n.signedUrl||!n.signedData)throw new Error("Missing signedUrl or signedData in response");let s=new FormData;Object.entries(n.signedData).forEach(([u,c])=>{s.append(u,c)}),s.append("file",new Blob([r],{type:o.contentType}),o.name);let a=await fetch(n.signedUrl,{method:"POST",body:s});if(a.status!==204)throw new Error(`S3 upload failed: ${a.status}`);return{id:n.id,name:n.name,status:"uploaded",s3UploadComplete:!0}},async get(o){return e.request(t,"/api/v1/core/files","GET",{params:{id:o,__namespace:i}})},async delete(o){await e.request(t,`/api/v1/core/files/${o}`,"DELETE")},async list(o={}){let r={__namespace:i};o.limit&&(r.limit=o.limit),o.cursor&&(r.cursor=o.cursor);let n=await e.request(t,"/api/v1/core/files","GET",{params:r});return{items:n?.items||[],nextCursor:n?.next}}}}function z(e,t){return{async get(){return e.request(t,"/api/v1/accounts/account","GET")},async update(i){await e.request(t,"/api/v1/accounts/account","PUT",{body:{user:i}})},async usage(){return e.request(t,"/api/v1/accounts/account/usage","GET")},async resendVerification(){await e.request(t,"/api/v1/accounts/account/resend-verification","POST")}}}function K(e,t,i,o){let r={async list(){return e.request(t,"/api/v1/config/connectors","GET")},async connections(){return e.request(t,"/api/v1/core/integrations","GET",{params:{query:"default",__namespace:o}})},async all(){let[n,s]=await Promise.all([r.list(),r.connections()]),a=Array.isArray(n)?n:n?.items||[],u=Array.isArray(s)?s:s?.items||[],c=new Map;for(let g of u){let l=g.source||g.id;c.has(l)||c.set(l,[]),c.get(l).push(g)}return a.map(g=>{let l=c.get(g.id)||[];return{...g,connections:l,connected:l.some(f=>f.connected),connectionCount:l.filter(f=>f.connected).length}})},async status(n){let s=await r.connections(),u=(Array.isArray(s)?s:s?.items||[]).filter(c=>c.source===n&&c.connected);return{connected:u.length>0,connections:u}},async connect(n){return e.request(i,`/api/v1/accounts/integrations/${n}/initialize`,"POST",{body:{__namespace:o}})},async disconnect(n,s){await e.request(i,`/api/v1/accounts/integrations/${n}/remove`,"POST",{body:{configurationId:s}})}};return r}function V(e,t){return{async get(){return e.request(t,"/api/v1/config/openapi","GET")}}}function Q(){return{info:(e,t)=>console.log(`[Foundation] ${e}`,t??""),warn:(e,t)=>console.warn(`[Foundation] ${e}`,t??""),error:(e,t)=>console.error(`[Foundation] ${e}`,t??""),event:(e,t)=>console.log(`[Foundation Event] ${e}`,t??"")}}0&&(module.exports={createFoundation});
1
+ "use strict";var L=Object.create;var U=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var G=Object.getPrototypeOf,J=Object.prototype.hasOwnProperty;var N=(e,t)=>{for(var i in t)U(e,i,{get:t[i],enumerable:!0})},E=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of M(t))!J.call(e,r)&&r!==i&&U(e,r,{get:()=>t[r],enumerable:!(s=H(t,r))||s.enumerable});return e};var v=(e,t,i)=>(i=e!=null?L(G(e)):{},E(t||!e||!e.__esModule?U(i,"default",{value:e,enumerable:!0}):i,e)),X=e=>E(U({},"__esModule",{value:!0}),e);var ne={};N(ne,{createFoundation:()=>q});module.exports=X(ne);function W(e){return e?.response!==void 0?e.response:e?.data!==void 0?e.data:e}function z(e,t){let i=t?.error;if(i){let r=i.message||"Unknown error",n=i.details;if(n?.length){let o=n.map(a=>a.field?`${a.field}: ${a.message}`:a.message).join(", ");r=r?`${r} ${o}`:o}return Object.assign(new Error(r),{code:i.code,type:i.code,details:n,status:e})}let s=t?.data?.message||t?.message;return s?Object.assign(new Error(s),{status:e}):Object.assign(new Error(`HTTP ${e}`),{status:e})}function b(e){function t(r){return{"X-Foundation-Mvp-Application-Id":e.appId,"X-Foundation-Mvp-Tenant-Id":e.tenantId,"X-Foundation-Mvp-Application-Version":e.version,"Content-Type":"application/json",Authorization:`Bearer ${r}`}}async function i(r,n,o,a={}){let c=await e.getToken(),u=t(c),f=`${r}${n}`;if(a.params){let m=new URLSearchParams;for(let[P,w]of Object.entries(a.params))w!=null&&m.set(P,String(w));let S=m.toString();S&&(f+=`?${S}`)}let l={method:o,headers:u};a.body!==void 0&&(l.body=JSON.stringify(a.body));let g=await fetch(f,l);if(!g.ok){let m={};try{m=await g.json()}catch{}throw z(g.status,m)}if(g.status===204)return null;let y=await g.json();return W(y)}async function s(r,n={}){return fetch(r,n)}return{request:i,rawFetch:s,headers:t}}async function R(e){switch(e.provider){case"auth0":{if(!e.auth0)throw new Error("Auth0 config required");let{createAuth0Client:t}=await import("@auth0/auth0-spa-js"),i=await t({domain:e.auth0.domain,clientId:e.auth0.clientId,authorizationParams:{audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email",redirect_uri:window.location.origin},useRefreshTokens:!0,cacheLocation:"localstorage"}),s=e.auth0.domain,r=e.auth0.clientId;return{login:n=>i.loginWithRedirect(n),logout:n=>i.logout({logoutParams:{returnTo:window.location.origin},...n}),getUser:async()=>{let n=await i.getUser();if(n)return{id:n.sub||"",email:n.email||"",name:n.name,picture:n.picture}},getTokenSilently:n=>i.getTokenSilently(n),isAuthenticated:()=>i.isAuthenticated(),async signIn(n,o){let a=await fetch(`https://${s}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"password",client_id:r,username:n,password:o,audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email"})});if(!a.ok){let c=await a.json().catch(()=>({}));throw new Error(c.error_description||c.message||"Sign in failed")}},async signUp(n,o,a){let c=await fetch(`https://${s}/dbconnections/signup`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:r,email:n,password:o,connection:"Username-Password-Authentication",...a})});if(!c.ok){let u=await c.json().catch(()=>({}));throw new Error(u.description||u.message||"Sign up failed")}},async forgotPassword(n){let o=await fetch(`https://${s}/dbconnections/change_password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:r,email:n,connection:"Username-Password-Authentication"})});if(!o.ok){let a=await o.json().catch(()=>({}));throw new Error(a.error_description||a.message||"Password reset request failed")}},async resetPassword(n,o){throw new Error("Auth0 password reset is completed via the email link, not a code")}}}case"cognito":{if(!e.cognito)throw new Error("Cognito config required");let{fetchAuthSession:t,signInWithRedirect:i,signOut:s,getCurrentUser:r}=await import("aws-amplify/auth"),{Amplify:n}=await import("aws-amplify");return n.configure({Auth:{Cognito:{userPoolId:e.cognito.userPoolId,userPoolClientId:e.cognito.clientId,loginWith:{oauth:{domain:e.cognito.domain.replace("https://",""),scopes:(e.cognito.scope||"openid profile email").split(" "),redirectSignIn:[window.location.origin],redirectSignOut:[window.location.origin],responseType:"code"}}}}}),{login:async()=>{await i()},logout:async()=>{await s()},getUser:async()=>{try{let o=await r();return{id:o.userId,email:o.signInDetails?.loginId||"",name:o.username}}catch{return}},getTokenSilently:async()=>{let a=(await t()).tokens?.accessToken?.toString();if(!a)throw new Error("No token available");return a},isAuthenticated:async()=>{try{return await r(),!0}catch{return!1}},async signIn(o,a){let{signIn:c}=await import("aws-amplify/auth");await c({username:o,password:a})},async signUp(o,a,c){let{signUp:u}=await import("aws-amplify/auth");await u({username:o,password:a,options:{userAttributes:{email:o,...c}}})},async forgotPassword(o){let{resetPassword:a}=await import("aws-amplify/auth");await a({username:o})},async resetPassword(o,a){let{confirmResetPassword:c}=await import("aws-amplify/auth");await c({username:"",confirmationCode:o,newPassword:a})}}}case"none":return{login:async()=>{},logout:async()=>{},getUser:async()=>{},getTokenSilently:async()=>"none",isAuthenticated:async()=>!0};default:throw new Error(`Unknown auth provider: ${e.provider}`)}}function F(e){let t=null,i=[];function s(){i.forEach(r=>{try{r(t)}catch{}})}return{get user(){return t},get isAuthenticated(){return!!t},async getToken(){return e.getTokenSilently()},async login(r){await e.login(r);let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null,s()},async logout(r){await e.logout(r),t=null,s()},async signIn(r,n){if(!e.signIn)throw new Error("signIn not supported by this auth provider");await e.signIn(r,n);let o=await e.getUser();t=o?{id:o.id,email:o.email,name:o.name,picture:o.picture}:null,s()},async signUp(r,n,o){if(!e.signUp)throw new Error("signUp not supported by this auth provider");await e.signUp(r,n,o)},async forgotPassword(r){if(!e.forgotPassword)throw new Error("forgotPassword not supported by this auth provider");await e.forgotPassword(r)},async resetPassword(r,n){if(!e.resetPassword)throw new Error("resetPassword not supported by this auth provider");await e.resetPassword(r,n)},onChange(r){return i.length>=100?(console.warn("[Foundation SDK] Auth listener limit reached."),()=>{}):(i.push(r),()=>{let n=i.indexOf(r);n>-1&&i.splice(n,1)})},async _initUser(){if(await e.isAuthenticated()){let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null}}}}function A(e){if(!e)throw new Error("Token parsing failed: Missing auth token");try{let[t,i]=e.split("?"),s=t.split(".");if(s.length!==3)throw new Error("Invalid JWT format");let r=atob(s[1]),n=JSON.parse(r);i&&new URLSearchParams(i).forEach((f,l)=>{n[l]=f});let o=n["BaseApplication/apiBaseUrl"];if(!o)throw new Error("Token missing apiBaseUrl");let a=n["BaseApplication/websocketBaseUrl"]||"",c=n["BaseApplication/accountBaseUrl"]||o;return{sub:n.sub||"",apiBaseUrl:o,accountBaseUrl:c,websocketBaseUrl:a,userId:n["BaseApplication/userId"]||"",namespace:n["BaseApplication/namespace"]}}catch(t){if(t instanceof Error&&t.message.startsWith("Token"))throw t;let i=t instanceof Error?t.message:"Failed to parse token";throw new Error(`Token parsing failed: ${i}`)}}async function q(e){let t=e.configUrl,i=e.appId,s=e.tenantId;try{let d=await fetch("/foundation-env.json");if(d.ok){let p=await d.json();p.configUrl&&(t=p.configUrl,i=p.applicationId||i,s=p.applicationTenant||s)}}catch{}if(!t)throw new Error("No configUrl provided and /foundation-env.json not found");let r={Accept:"application/json","Cache-Control":"no-cache"};i&&(r["X-Foundation-Mvp-Application-Id"]=i),s&&(r["X-Foundation-Mvp-Tenant-Id"]=s);let n=await fetch(t,{headers:r});if(!n.ok)throw new Error(`Failed to fetch config: ${n.statusText}`);let o=await n.json(),a=o.data??o,c=a.auth||{provider:"none"},u=e.auth||await R(c),l=F(u);await l._initUser();let g,y;if(e.baseUrl)g=e.baseUrl,y=e.baseUrl;else if(c.apiUrls?.apiBaseUrl)g=c.apiUrls.apiBaseUrl,y=c.apiUrls.accountBaseUrl||g;else{let d=await u.getTokenSilently(),p=A(d);g=p.apiBaseUrl,y=p.accountBaseUrl}let m=i||a.app?.id||a.tenant?.identifier||"",S=s||a.tenant?.identifier||"",P=a.app?.version||a.core?.version||"0.0.0",w=b({appId:m,tenantId:S,version:P,getToken:()=>u.getTokenSilently()}),T={};try{T=await w.request(g,"/api/v1/config/init","GET")||{}}catch(d){console.warn("[Foundation SDK] Backend config fetch failed:",d)}let h={...a,...T},C="";try{let d=await u.getTokenSilently();d&&d!=="none"&&(C=A(d).namespace||"")}catch{}let O={get app(){let d=h.app||{};return{id:d.id||m,name:d.name||"",version:d.version||P,environment:d.environment||"",...d}},get features(){return h.features||{}},get plans(){return h.plans||[]},get theme(){let d=h.theme||{};return{colors:d.colors||{},dark:d.dark||{},defaultColorScheme:d.defaultColorScheme}},get connectors(){return h.connectors||{}},get resources(){return h.resources||{}},get auth(){let{provider:d,...p}=c;return{provider:d,...p}},get raw(){return h}},$=K(w,g),_=V(w,g,C),x=Q(w,y),D=Y(w,g,y,C),j=Z(w,g),B=ee(),k=[];return{get ready(){return Promise.resolve()},get isReady(){return!0},auth:l,db:$,files:_,integration:D,account:x,config:O,openapi:j,log:B,on(d,p){return d==="entity.changed"?(k.push(p),()=>{let I=k.indexOf(p);I>-1&&k.splice(I,1)}):()=>{}}}}function K(e,t){return{async list(i,s={}){let{filters:r,limit:n,cursor:o,orderBy:a,orderDir:c}=s,u={...r};return n&&(u.limit=n),o&&(u.next=o),a&&(u.orderBy=a),c&&(u.orderDir=c),e.request(t,`/api/v1/core/${i}`,"GET",{params:u})},async get(i,s){return e.request(t,`/api/v1/core/${i}`,"GET",{params:{id:s}})},async create(i,s){return e.request(t,`/api/v1/core/${i}`,"POST",{body:s})},async update(i,s,r){return e.request(t,`/api/v1/core/${i}`,"PUT",{body:{id:s,...r}})},async save(i,s){try{return await e.request(t,`/api/v1/core/${i}`,"PUT",{body:s})}catch{return e.request(t,`/api/v1/core/${i}`,"POST",{body:s})}},async delete(i,s){await e.request(t,`/api/v1/core/${i}`,"DELETE",{body:{id:s}})}}}function V(e,t,i){return{async initiate(s){return e.request(t,"/api/v1/core/upload","POST",{body:{...s,__namespace:i}})},async upload(s){let r;s.file instanceof ArrayBuffer?r=s.file:r=await s.file.arrayBuffer();let n=await e.request(t,"/api/v1/core/upload","POST",{body:{name:s.name,contentType:s.contentType,contentLength:r.byteLength,sha256:s.sha256,__namespace:i}});if(!n.signedUrl||!n.signedData)throw new Error("Missing signedUrl or signedData in response");let o=new FormData;Object.entries(n.signedData).forEach(([c,u])=>{o.append(c,u)}),o.append("file",new Blob([r],{type:s.contentType}),s.name);let a=await fetch(n.signedUrl,{method:"POST",body:o});if(a.status!==204)throw new Error(`S3 upload failed: ${a.status}`);return{id:n.id,name:n.name,status:"uploaded",s3UploadComplete:!0}},async get(s){return e.request(t,"/api/v1/core/files","GET",{params:{id:s,__namespace:i}})},async delete(s){await e.request(t,`/api/v1/core/files/${s}`,"DELETE")},async list(s={}){let r={__namespace:i};s.limit&&(r.limit=s.limit),s.cursor&&(r.cursor=s.cursor);let n=await e.request(t,"/api/v1/core/files","GET",{params:r});return{items:n?.items||[],nextCursor:n?.next}}}}function Q(e,t){return{async get(){return e.request(t,"/api/v1/accounts/account","GET")},async update(i){await e.request(t,"/api/v1/accounts/account","PUT",{body:{user:i}})},async usage(){return e.request(t,"/api/v1/accounts/account/usage","GET")},async resendVerification(){await e.request(t,"/api/v1/accounts/account/resend-verification","POST")}}}function Y(e,t,i,s){let r={async list(){return e.request(t,"/api/v1/config/connectors","GET")},async connections(){return e.request(t,"/api/v1/core/integrations","GET",{params:{query:"default",__namespace:s}})},async all(){let[n,o]=await Promise.all([r.list(),r.connections()]),a=Array.isArray(n)?n:n?.items||[],c=Array.isArray(o)?o:o?.items||[],u=new Map;for(let f of c){let l=f.source||f.id;u.has(l)||u.set(l,[]),u.get(l).push(f)}return a.map(f=>{let l=u.get(f.id)||[];return{...f,connections:l,connected:l.some(g=>g.connected),connectionCount:l.filter(g=>g.connected).length}})},async status(n){let o=await r.connections(),c=(Array.isArray(o)?o:o?.items||[]).filter(u=>u.source===n&&u.connected);return{connected:c.length>0,connections:c}},async connect(n){return e.request(i,`/api/v1/accounts/integrations/${n}/initialize`,"POST",{body:{__namespace:s}})},async disconnect(n,o){await e.request(i,`/api/v1/accounts/integrations/${n}/remove`,"POST",{body:{configurationId:o}})}};return r}function Z(e,t){return{async get(){return e.request(t,"/api/v1/config/openapi","GET")}}}function ee(){return{info:(e,t)=>console.log(`[Foundation] ${e}`,t??""),warn:(e,t)=>console.warn(`[Foundation] ${e}`,t??""),error:(e,t)=>console.error(`[Foundation] ${e}`,t??""),event:(e,t)=>console.log(`[Foundation Event] ${e}`,t??"")}}0&&(module.exports={createFoundation});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/http.ts","../src/auth.ts","../src/jwt.ts","../src/foundation.ts"],"sourcesContent":["export { createFoundation } from './foundation'\n\nexport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n User,\n FileMetadata,\n EntityChangeEvent,\n AuthClient,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService\n} from './types'\n","/**\n * HTTP layer for Foundation API calls.\n * Handles request construction, response unwrapping, and error extraction.\n */\n\n/**\n * Unwrap backend response envelope.\n * The API wraps responses in { response: ... } or { data: ... }.\n */\nexport function unwrapResponse(json: Record<string, unknown>): unknown {\n if (json?.response !== undefined) return json.response\n if (json?.data !== undefined) return json.data\n return json\n}\n\n/**\n * Extract a meaningful error from a failed API response.\n */\nexport function extractError(status: number, body: Record<string, unknown>): Error {\n const errorObj = body?.error as Record<string, unknown> | undefined\n\n if (errorObj) {\n let message = errorObj.message as string || 'Unknown error'\n const details = errorObj.details as Array<{ field?: string; message?: string }> | undefined\n if (details?.length) {\n const detailMessages = details\n .map(d => d.field ? `${d.field}: ${d.message}` : d.message)\n .join(', ')\n message = message ? `${message} ${detailMessages}` : detailMessages\n }\n return Object.assign(new Error(message), {\n code: errorObj.code,\n type: errorObj.code,\n details,\n status\n })\n }\n\n const customMessage = (body?.data as Record<string, unknown>)?.message || body?.message\n if (customMessage) {\n return Object.assign(new Error(customMessage as string), { status })\n }\n\n return Object.assign(new Error(`HTTP ${status}`), { status })\n}\n\nexport interface HttpClientConfig {\n appId: string\n tenantId: string\n version: string\n getToken: () => Promise<string>\n}\n\nexport function createHttpClient(config: HttpClientConfig) {\n function headers(token: string): Record<string, string> {\n return {\n 'X-Foundation-Mvp-Application-Id': config.appId,\n 'X-Foundation-Mvp-Tenant-Id': config.tenantId,\n 'X-Foundation-Mvp-Application-Version': config.version,\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n }\n }\n\n async function request(\n baseUrl: string,\n path: string,\n method: string,\n options: { params?: Record<string, unknown>; body?: unknown } = {}\n ): Promise<unknown> {\n const token = await config.getToken()\n const hdrs = headers(token)\n\n let url = `${baseUrl}${path}`\n if (options.params) {\n const searchParams = new URLSearchParams()\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value))\n }\n }\n const qs = searchParams.toString()\n if (qs) url += `?${qs}`\n }\n\n const fetchOptions: RequestInit = { method, headers: hdrs }\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body)\n }\n\n const response = await fetch(url, fetchOptions)\n\n if (!response.ok) {\n let body: Record<string, unknown> = {}\n try { body = await response.json() } catch { /* no json body */ }\n throw extractError(response.status, body)\n }\n\n if (response.status === 204) return null\n\n const json = await response.json()\n return unwrapResponse(json as Record<string, unknown>)\n }\n\n /** Raw fetch with auth headers but no unwrapping (for S3 uploads etc.) */\n async function rawFetch(url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, options)\n }\n\n return { request, rawFetch, headers }\n}\n\nexport type HttpClient = ReturnType<typeof createHttpClient>\n","/**\n * Auth provider factory.\n * Creates the right auth client based on config (Cognito/Auth0/none).\n * Supports custom auth client override.\n */\nimport type { AuthClient, AuthService, User } from './types'\n\nconst MAX_LISTENERS = 100\n\nexport interface AuthProviderConfig {\n provider: string\n auth0?: { domain: string; clientId: string; audience?: string; scope?: string }\n cognito?: { userPoolId: string; clientId: string; region: string; domain: string; scope?: string }\n apiUrls?: { apiBaseUrl: string; accountBaseUrl?: string; websocketBaseUrl?: string }\n}\n\nexport async function createAuthClient(config: AuthProviderConfig): Promise<AuthClient> {\n switch (config.provider) {\n case 'auth0': {\n if (!config.auth0) throw new Error('Auth0 config required')\n const { createAuth0Client } = await import('@auth0/auth0-spa-js')\n const client = await createAuth0Client({\n domain: config.auth0.domain,\n clientId: config.auth0.clientId,\n authorizationParams: {\n audience: config.auth0.audience,\n scope: config.auth0.scope || 'openid profile email',\n redirect_uri: window.location.origin\n },\n useRefreshTokens: true,\n cacheLocation: 'localstorage'\n })\n\n const auth0Domain = config.auth0.domain\n const auth0ClientId = config.auth0.clientId\n\n return {\n login: (options) => client.loginWithRedirect(options),\n logout: (options) => client.logout({ logoutParams: { returnTo: window.location.origin }, ...options }),\n getUser: async () => {\n const user = await client.getUser()\n if (!user) return undefined\n return { id: user.sub || '', email: user.email || '', name: user.name, picture: user.picture }\n },\n getTokenSilently: (options) => client.getTokenSilently(options),\n isAuthenticated: () => client.isAuthenticated(),\n\n async signIn(email: string, password: string) {\n // Auth0 Resource Owner Password Grant\n const response = await fetch(`https://${auth0Domain}/oauth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'password',\n client_id: auth0ClientId,\n username: email,\n password,\n audience: config.auth0!.audience,\n scope: config.auth0!.scope || 'openid profile email'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Sign in failed')\n }\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n password,\n connection: 'Username-Password-Authentication',\n ...metadata\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.description || err.message || 'Sign up failed')\n }\n },\n\n async forgotPassword(email: string) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/change_password`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n connection: 'Username-Password-Authentication'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Password reset request failed')\n }\n },\n\n async resetPassword(_code: string, _newPassword: string) {\n // Auth0 handles reset via email link, not code-based flow\n throw new Error('Auth0 password reset is completed via the email link, not a code')\n }\n }\n }\n\n case 'cognito': {\n if (!config.cognito) throw new Error('Cognito config required')\n const { fetchAuthSession, signInWithRedirect, signOut, getCurrentUser } = await import('aws-amplify/auth')\n const { Amplify } = await import('aws-amplify')\n\n Amplify.configure({\n Auth: {\n Cognito: {\n userPoolId: config.cognito.userPoolId,\n userPoolClientId: config.cognito.clientId,\n loginWith: {\n oauth: {\n domain: config.cognito.domain.replace('https://', ''),\n scopes: (config.cognito.scope || 'openid profile email').split(' '),\n redirectSignIn: [window.location.origin],\n redirectSignOut: [window.location.origin],\n responseType: 'code'\n }\n }\n }\n }\n })\n\n return {\n login: async () => { await signInWithRedirect() },\n logout: async () => { await signOut() },\n getUser: async () => {\n try {\n const user = await getCurrentUser()\n return { id: user.userId, email: user.signInDetails?.loginId || '', name: user.username }\n } catch { return undefined }\n },\n getTokenSilently: async () => {\n const session = await fetchAuthSession()\n const token = session.tokens?.accessToken?.toString()\n if (!token) throw new Error('No token available')\n return token\n },\n isAuthenticated: async () => {\n try {\n await getCurrentUser()\n return true\n } catch { return false }\n },\n\n async signIn(email: string, password: string) {\n const { signIn } = await import('aws-amplify/auth')\n await signIn({ username: email, password })\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const { signUp } = await import('aws-amplify/auth')\n await signUp({\n username: email,\n password,\n options: { userAttributes: { email, ...metadata } }\n })\n },\n\n async forgotPassword(email: string) {\n const { resetPassword } = await import('aws-amplify/auth')\n await resetPassword({ username: email })\n },\n\n async resetPassword(code: string, newPassword: string) {\n const { confirmResetPassword } = await import('aws-amplify/auth')\n // Note: caller must track the username from the forgotPassword call\n await confirmResetPassword({ username: '', confirmationCode: code, newPassword })\n }\n }\n }\n\n case 'none':\n return {\n login: async () => {},\n logout: async () => {},\n getUser: async () => undefined,\n getTokenSilently: async () => 'none',\n isAuthenticated: async () => true\n }\n\n default:\n throw new Error(`Unknown auth provider: ${config.provider}`)\n }\n}\n\n/**\n * Wrap an AuthClient into the reactive AuthService interface.\n */\nexport function createAuthService(client: AuthClient): AuthService {\n let user: User | null = null\n const listeners: Array<(user: User | null) => void> = []\n\n function notifyListeners() {\n listeners.forEach(fn => { try { fn(user) } catch { /* */ } })\n }\n\n return {\n get user() { return user },\n get isAuthenticated() { return !!user },\n\n async getToken() {\n return client.getTokenSilently()\n },\n\n async login(options) {\n await client.login(options)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async logout(options) {\n await client.logout(options)\n user = null\n notifyListeners()\n },\n\n async signIn(email: string, password: string) {\n if (!client.signIn) throw new Error('signIn not supported by this auth provider')\n await client.signIn(email, password)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n if (!client.signUp) throw new Error('signUp not supported by this auth provider')\n await client.signUp(email, password, metadata)\n },\n\n async forgotPassword(email: string) {\n if (!client.forgotPassword) throw new Error('forgotPassword not supported by this auth provider')\n await client.forgotPassword(email)\n },\n\n async resetPassword(code: string, newPassword: string) {\n if (!client.resetPassword) throw new Error('resetPassword not supported by this auth provider')\n await client.resetPassword(code, newPassword)\n },\n\n onChange(callback) {\n if (listeners.length >= MAX_LISTENERS) {\n console.warn('[Foundation SDK] Auth listener limit reached.')\n return () => {}\n }\n listeners.push(callback)\n return () => {\n const idx = listeners.indexOf(callback)\n if (idx > -1) listeners.splice(idx, 1)\n }\n },\n\n /** @internal Initialize user state from auth client */\n async _initUser() {\n const authenticated = await client.isAuthenticated()\n if (authenticated) {\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n }\n }\n } as AuthService & { _initUser(): Promise<void> }\n}\n","export interface JwtClaims {\n sub: string\n apiBaseUrl: string\n accountBaseUrl: string\n websocketBaseUrl: string\n userId: string\n namespace?: string\n}\n\nexport function parseJwt(token: string): JwtClaims {\n if (!token) {\n throw new Error('Token parsing failed: Missing auth token')\n }\n\n try {\n // Auth0 tokens can have query params appended: \"jwt?param=value\"\n const [jwtPart, queryPart] = token.split('?')\n\n const parts = jwtPart.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n const payloadStr = atob(parts[1])\n const jwtPayload = JSON.parse(payloadStr)\n\n // Merge query params if present\n if (queryPart) {\n const params = new URLSearchParams(queryPart)\n params.forEach((value, key) => {\n jwtPayload[key] = value\n })\n }\n\n const apiBaseUrl = jwtPayload['BaseApplication/apiBaseUrl']\n if (!apiBaseUrl) {\n throw new Error('Token missing apiBaseUrl')\n }\n\n const websocketBaseUrl = jwtPayload['BaseApplication/websocketBaseUrl'] || ''\n const accountBaseUrl = jwtPayload['BaseApplication/accountBaseUrl'] || apiBaseUrl\n\n return {\n sub: jwtPayload.sub || '',\n apiBaseUrl,\n accountBaseUrl,\n websocketBaseUrl,\n userId: jwtPayload['BaseApplication/userId'] || '',\n namespace: jwtPayload['BaseApplication/namespace']\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith('Token')) {\n throw err\n }\n const message = err instanceof Error ? err.message : 'Failed to parse token'\n throw new Error(`Token parsing failed: ${message}`)\n }\n}\n","/**\n * Foundation SDK — typed API client for the Foundation platform.\n *\n * One input: a config URL. The SDK fetches it, discovers auth, API URLs,\n * features, plans, theme, connectors — everything. Self-configuring.\n */\nimport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService,\n EntityChangeEvent,\n User\n} from './types'\nimport { createHttpClient, unwrapResponse, type HttpClient } from './http'\nimport { createAuthClient, createAuthService, type AuthProviderConfig } from './auth'\nimport { parseJwt } from './jwt'\n\nexport async function createFoundation(options: FoundationConfig): Promise<Foundation> {\n // 1. Fetch public config\n const configHeaders: Record<string, string> = { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }\n if (options.appId) configHeaders['X-Foundation-Mvp-Application-Id'] = options.appId\n if (options.tenantId) configHeaders['X-Foundation-Mvp-Tenant-Id'] = options.tenantId\n\n const publicConfigResponse = await fetch(options.configUrl, { headers: configHeaders })\n if (!publicConfigResponse.ok) {\n throw new Error(`Failed to fetch config: ${publicConfigResponse.statusText}`)\n }\n const rawPublicConfig = await publicConfigResponse.json()\n const publicConfig = rawPublicConfig.data ?? rawPublicConfig\n\n // 2. Set up auth\n const authConfig: AuthProviderConfig = publicConfig.auth || { provider: 'none' }\n const authClient = options.auth || await createAuthClient(authConfig)\n const authServiceRaw = createAuthService(authClient)\n const authService = authServiceRaw as AuthService & { _initUser(): Promise<void> }\n await authService._initUser()\n\n // 3. Determine API URLs\n let apiBaseUrl: string\n let accountBaseUrl: string\n\n if (options.baseUrl) {\n // Explicit override (e.g. '/api' with a dev proxy)\n apiBaseUrl = options.baseUrl\n accountBaseUrl = options.baseUrl\n } else if (authConfig.apiUrls?.apiBaseUrl) {\n // API URLs from public config (no-auth mode or explicit)\n apiBaseUrl = authConfig.apiUrls.apiBaseUrl\n accountBaseUrl = authConfig.apiUrls.accountBaseUrl || apiBaseUrl\n } else {\n // API URLs from JWT token\n const token = await authClient.getTokenSilently()\n const claims = parseJwt(token)\n apiBaseUrl = claims.apiBaseUrl\n accountBaseUrl = claims.accountBaseUrl\n }\n\n // 4. Create HTTP client\n const appId = options.appId || publicConfig.app?.id || publicConfig.tenant?.identifier || ''\n const tenantId = options.tenantId || publicConfig.tenant?.identifier || ''\n const version = publicConfig.app?.version || publicConfig.core?.version || '0.0.0'\n\n const http = createHttpClient({\n appId,\n tenantId,\n version,\n getToken: () => authClient.getTokenSilently()\n })\n\n // 5. Fetch backend config (authenticated)\n let backendConfig: Record<string, unknown> = {}\n try {\n const cfg = await http.request(apiBaseUrl, '/api/v1/config/init', 'GET')\n backendConfig = (cfg || {}) as Record<string, unknown>\n } catch (err) {\n console.warn('[Foundation SDK] Backend config fetch failed:', err)\n }\n\n // 6. Merge configs\n const mergedConfig = { ...publicConfig, ...backendConfig }\n\n // Determine namespace from JWT if available\n let namespace = ''\n try {\n const token = await authClient.getTokenSilently()\n if (token && token !== 'none') {\n const claims = parseJwt(token)\n namespace = claims.namespace || ''\n }\n } catch { /* no token yet */ }\n\n // 7. Build config service\n const config: FullConfig = {\n get app() {\n const app = mergedConfig.app as Record<string, unknown> || {}\n return {\n id: (app.id || appId) as string,\n name: (app.name || '') as string,\n version: (app.version || version) as string,\n environment: (app.environment || '') as string,\n ...app\n }\n },\n get features() { return (mergedConfig.features || {}) as Record<string, unknown> },\n get plans() { return (mergedConfig.plans || []) as unknown[] },\n get theme() {\n const theme = mergedConfig.theme as Record<string, unknown> || {}\n return {\n colors: (theme.colors || {}) as Record<string, string>,\n dark: (theme.dark || {}) as Record<string, string>,\n defaultColorScheme: theme.defaultColorScheme as string | undefined\n }\n },\n get connectors() { return (mergedConfig.connectors || {}) as Record<string, unknown> },\n get resources() { return (mergedConfig.resources || {}) as Record<string, string> },\n get auth() {\n const { provider, ...rest } = authConfig\n return { provider, ...rest } as { provider: string; [key: string]: unknown }\n },\n get raw() { return mergedConfig }\n }\n\n // 8. Build services\n const db = createDbService(http, apiBaseUrl)\n const files = createFilesService(http, apiBaseUrl, namespace)\n const account = createAccountService(http, accountBaseUrl)\n const integration = createIntegrationService(http, apiBaseUrl, accountBaseUrl, namespace)\n const openapi = createOpenApiService(http, apiBaseUrl)\n const log = createLogService()\n\n // Entity change listeners (WebSocket support is future)\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const foundation: Foundation = {\n get ready() { return Promise.resolve() },\n get isReady() { return true },\n auth: authService,\n db,\n files,\n integration,\n account,\n config,\n openapi,\n log,\n on(event, callback) {\n if (event === 'entity.changed') {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n }\n return () => {}\n }\n }\n\n return foundation\n}\n\n// --- Service factories ---\n\nfunction createDbService(http: HttpClient, apiBase: string): DbService {\n return {\n async list(entity, options = {}) {\n const { filters, limit, cursor, orderBy, orderDir } = options\n const params: Record<string, unknown> = { ...filters }\n if (limit) params.limit = limit\n if (cursor) params.next = cursor\n if (orderBy) params.orderBy = orderBy\n if (orderDir) params.orderDir = orderDir\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params }) as Promise<any>\n },\n async get(entity, id) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params: { id } }) as Promise<any>\n },\n async create(entity, data) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n },\n async update(entity, id, updates) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: { id, ...updates } }) as Promise<any>\n },\n async save(entity, data) {\n try {\n return await http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: data }) as Promise<any>\n } catch {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n }\n },\n async delete(entity, id) {\n await http.request(apiBase, `/api/v1/core/${entity}`, 'DELETE', { body: { id } })\n }\n }\n}\n\nfunction createFilesService(http: HttpClient, apiBase: string, namespace: string): FilesService {\n return {\n async initiate(options) {\n return http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { ...options, __namespace: namespace }\n }) as Promise<any>\n },\n async upload(options) {\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n fileData = await options.file.arrayBuffer()\n }\n\n const uploadData = await http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { name: options.name, contentType: options.contentType, contentLength: fileData.byteLength, sha256: options.sha256, __namespace: namespace }\n }) as { id: string; name: string; signedUrl: string; signedData: Record<string, string> }\n\n if (!uploadData.signedUrl || !uploadData.signedData) {\n throw new Error('Missing signedUrl or signedData in response')\n }\n\n const formData = new FormData()\n Object.entries(uploadData.signedData).forEach(([key, value]) => {\n formData.append(key, value)\n })\n formData.append('file', new Blob([fileData], { type: options.contentType }), options.name)\n\n const s3Response = await fetch(uploadData.signedUrl, { method: 'POST', body: formData })\n if (s3Response.status !== 204) {\n throw new Error(`S3 upload failed: ${s3Response.status}`)\n }\n\n return { id: uploadData.id, name: uploadData.name, status: 'uploaded', s3UploadComplete: true }\n },\n async get(fileId) {\n return http.request(apiBase, '/api/v1/core/files', 'GET', {\n params: { id: fileId, __namespace: namespace }\n }) as Promise<any>\n },\n async delete(fileId) {\n await http.request(apiBase, `/api/v1/core/files/${fileId}`, 'DELETE')\n },\n async list(options = {}) {\n const params: Record<string, unknown> = { __namespace: namespace }\n if (options.limit) params.limit = options.limit\n if (options.cursor) params.cursor = options.cursor\n const result = await http.request(apiBase, '/api/v1/core/files', 'GET', { params }) as {\n items?: unknown[]; next?: string\n }\n return { items: result?.items || [], nextCursor: result?.next } as any\n }\n }\n}\n\nfunction createAccountService(http: HttpClient, accountBase: string): AccountService {\n return {\n async get() {\n return http.request(accountBase, '/api/v1/accounts/account', 'GET') as Promise<any>\n },\n async update(data) {\n await http.request(accountBase, '/api/v1/accounts/account', 'PUT', { body: { user: data } })\n },\n async usage() {\n return http.request(accountBase, '/api/v1/accounts/account/usage', 'GET') as Promise<any>\n },\n async resendVerification() {\n await http.request(accountBase, '/api/v1/accounts/account/resend-verification', 'POST')\n }\n }\n}\n\nfunction createIntegrationService(http: HttpClient, apiBase: string, accountBase: string, namespace: string): IntegrationService {\n const service: IntegrationService = {\n async list() {\n return http.request(apiBase, '/api/v1/config/connectors', 'GET') as Promise<any>\n },\n async connections() {\n return http.request(apiBase, '/api/v1/core/integrations', 'GET', {\n params: { query: 'default', __namespace: namespace }\n }) as Promise<any>\n },\n async all() {\n const [rawCatalog, rawConnections] = await Promise.all([\n service.list(),\n service.connections()\n ])\n\n const catalog = (Array.isArray(rawCatalog) ? rawCatalog : (rawCatalog as any)?.items || []) as Integration[]\n const connections = (Array.isArray(rawConnections) ? rawConnections : (rawConnections as any)?.items || []) as IntegrationConnection[]\n\n const bySource = new Map<string, IntegrationConnection[]>()\n for (const conn of connections) {\n const source = conn.source || conn.id\n if (!bySource.has(source)) bySource.set(source, [])\n bySource.get(source)!.push(conn)\n }\n\n return catalog.map(item => {\n const conns = bySource.get(item.id) || []\n return {\n ...item,\n connections: conns,\n connected: conns.some(c => c.connected),\n connectionCount: conns.filter(c => c.connected).length\n } as IntegrationDetail\n })\n },\n async status(source) {\n const conns = await service.connections()\n const items = (Array.isArray(conns) ? conns : (conns as any)?.items || []) as IntegrationConnection[]\n const filtered = items.filter(c => c.source === source && c.connected)\n return { connected: filtered.length > 0, connections: filtered }\n },\n async connect(source) {\n return http.request(accountBase, `/api/v1/accounts/integrations/${source}/initialize`, 'POST', {\n body: { __namespace: namespace }\n }) as Promise<any>\n },\n async disconnect(source, configurationId) {\n await http.request(accountBase, `/api/v1/accounts/integrations/${source}/remove`, 'POST', {\n body: { configurationId }\n })\n }\n }\n return service\n}\n\nfunction createOpenApiService(http: HttpClient, apiBase: string): OpenApiService {\n return {\n async get() {\n return http.request(apiBase, '/api/v1/config/openapi', 'GET') as Promise<any>\n }\n }\n}\n\nfunction createLogService(): LogService {\n return {\n info: (message, context) => console.log(`[Foundation] ${message}`, context ?? ''),\n warn: (message, context) => console.warn(`[Foundation] ${message}`, context ?? ''),\n error: (message, context) => console.error(`[Foundation] ${message}`, context ?? ''),\n event: (event, data) => console.log(`[Foundation Event] ${event}`, data ?? '')\n }\n}\n"],"mappings":"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","names":["index_exports","__export","createFoundation","__toCommonJS","unwrapResponse","json","extractError","status","body","errorObj","message","details","detailMessages","d","customMessage","createHttpClient","config","headers","token","request","baseUrl","path","method","options","hdrs","url","searchParams","key","value","qs","fetchOptions","response","rawFetch","createAuthClient","config","createAuth0Client","client","auth0Domain","auth0ClientId","options","user","email","password","response","err","metadata","_code","_newPassword","fetchAuthSession","signInWithRedirect","signOut","getCurrentUser","Amplify","token","signIn","signUp","resetPassword","code","newPassword","confirmResetPassword","createAuthService","listeners","notifyListeners","fn","authUser","callback","idx","parseJwt","token","jwtPart","queryPart","parts","payloadStr","jwtPayload","value","key","apiBaseUrl","websocketBaseUrl","accountBaseUrl","err","message","createFoundation","options","configHeaders","publicConfigResponse","rawPublicConfig","publicConfig","authConfig","authClient","createAuthClient","authService","createAuthService","apiBaseUrl","accountBaseUrl","token","claims","parseJwt","appId","tenantId","version","http","createHttpClient","backendConfig","err","mergedConfig","namespace","config","app","theme","provider","rest","db","createDbService","files","createFilesService","account","createAccountService","integration","createIntegrationService","openapi","createOpenApiService","log","createLogService","entityListeners","event","callback","idx","apiBase","entity","filters","limit","cursor","orderBy","orderDir","params","id","data","updates","fileData","uploadData","formData","key","value","s3Response","fileId","result","accountBase","service","rawCatalog","rawConnections","catalog","connections","bySource","conn","source","item","conns","c","filtered","configurationId","message","context"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/http.ts","../src/auth.ts","../src/jwt.ts","../src/foundation.ts"],"sourcesContent":["export { createFoundation } from './foundation'\n\nexport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n User,\n FileMetadata,\n EntityChangeEvent,\n AuthClient,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService\n} from './types'\n","/**\n * HTTP layer for Foundation API calls.\n * Handles request construction, response unwrapping, and error extraction.\n */\n\n/**\n * Unwrap backend response envelope.\n * The API wraps responses in { response: ... } or { data: ... }.\n */\nexport function unwrapResponse(json: Record<string, unknown>): unknown {\n if (json?.response !== undefined) return json.response\n if (json?.data !== undefined) return json.data\n return json\n}\n\n/**\n * Extract a meaningful error from a failed API response.\n */\nexport function extractError(status: number, body: Record<string, unknown>): Error {\n const errorObj = body?.error as Record<string, unknown> | undefined\n\n if (errorObj) {\n let message = errorObj.message as string || 'Unknown error'\n const details = errorObj.details as Array<{ field?: string; message?: string }> | undefined\n if (details?.length) {\n const detailMessages = details\n .map(d => d.field ? `${d.field}: ${d.message}` : d.message)\n .join(', ')\n message = message ? `${message} ${detailMessages}` : detailMessages\n }\n return Object.assign(new Error(message), {\n code: errorObj.code,\n type: errorObj.code,\n details,\n status\n })\n }\n\n const customMessage = (body?.data as Record<string, unknown>)?.message || body?.message\n if (customMessage) {\n return Object.assign(new Error(customMessage as string), { status })\n }\n\n return Object.assign(new Error(`HTTP ${status}`), { status })\n}\n\nexport interface HttpClientConfig {\n appId: string\n tenantId: string\n version: string\n getToken: () => Promise<string>\n}\n\nexport function createHttpClient(config: HttpClientConfig) {\n function headers(token: string): Record<string, string> {\n return {\n 'X-Foundation-Mvp-Application-Id': config.appId,\n 'X-Foundation-Mvp-Tenant-Id': config.tenantId,\n 'X-Foundation-Mvp-Application-Version': config.version,\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n }\n }\n\n async function request(\n baseUrl: string,\n path: string,\n method: string,\n options: { params?: Record<string, unknown>; body?: unknown } = {}\n ): Promise<unknown> {\n const token = await config.getToken()\n const hdrs = headers(token)\n\n let url = `${baseUrl}${path}`\n if (options.params) {\n const searchParams = new URLSearchParams()\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value))\n }\n }\n const qs = searchParams.toString()\n if (qs) url += `?${qs}`\n }\n\n const fetchOptions: RequestInit = { method, headers: hdrs }\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body)\n }\n\n const response = await fetch(url, fetchOptions)\n\n if (!response.ok) {\n let body: Record<string, unknown> = {}\n try { body = await response.json() } catch { /* no json body */ }\n throw extractError(response.status, body)\n }\n\n if (response.status === 204) return null\n\n const json = await response.json()\n return unwrapResponse(json as Record<string, unknown>)\n }\n\n /** Raw fetch with auth headers but no unwrapping (for S3 uploads etc.) */\n async function rawFetch(url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, options)\n }\n\n return { request, rawFetch, headers }\n}\n\nexport type HttpClient = ReturnType<typeof createHttpClient>\n","/**\n * Auth provider factory.\n * Creates the right auth client based on config (Cognito/Auth0/none).\n * Supports custom auth client override.\n */\nimport type { AuthClient, AuthService, User } from './types'\n\nconst MAX_LISTENERS = 100\n\nexport interface AuthProviderConfig {\n provider: string\n auth0?: { domain: string; clientId: string; audience?: string; scope?: string }\n cognito?: { userPoolId: string; clientId: string; region: string; domain: string; scope?: string }\n apiUrls?: { apiBaseUrl: string; accountBaseUrl?: string; websocketBaseUrl?: string }\n}\n\nexport async function createAuthClient(config: AuthProviderConfig): Promise<AuthClient> {\n switch (config.provider) {\n case 'auth0': {\n if (!config.auth0) throw new Error('Auth0 config required')\n const { createAuth0Client } = await import('@auth0/auth0-spa-js')\n const client = await createAuth0Client({\n domain: config.auth0.domain,\n clientId: config.auth0.clientId,\n authorizationParams: {\n audience: config.auth0.audience,\n scope: config.auth0.scope || 'openid profile email',\n redirect_uri: window.location.origin\n },\n useRefreshTokens: true,\n cacheLocation: 'localstorage'\n })\n\n const auth0Domain = config.auth0.domain\n const auth0ClientId = config.auth0.clientId\n\n return {\n login: (options) => client.loginWithRedirect(options),\n logout: (options) => client.logout({ logoutParams: { returnTo: window.location.origin }, ...options }),\n getUser: async () => {\n const user = await client.getUser()\n if (!user) return undefined\n return { id: user.sub || '', email: user.email || '', name: user.name, picture: user.picture }\n },\n getTokenSilently: (options) => client.getTokenSilently(options),\n isAuthenticated: () => client.isAuthenticated(),\n\n async signIn(email: string, password: string) {\n // Auth0 Resource Owner Password Grant\n const response = await fetch(`https://${auth0Domain}/oauth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'password',\n client_id: auth0ClientId,\n username: email,\n password,\n audience: config.auth0!.audience,\n scope: config.auth0!.scope || 'openid profile email'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Sign in failed')\n }\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n password,\n connection: 'Username-Password-Authentication',\n ...metadata\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.description || err.message || 'Sign up failed')\n }\n },\n\n async forgotPassword(email: string) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/change_password`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n connection: 'Username-Password-Authentication'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Password reset request failed')\n }\n },\n\n async resetPassword(_code: string, _newPassword: string) {\n // Auth0 handles reset via email link, not code-based flow\n throw new Error('Auth0 password reset is completed via the email link, not a code')\n }\n }\n }\n\n case 'cognito': {\n if (!config.cognito) throw new Error('Cognito config required')\n const { fetchAuthSession, signInWithRedirect, signOut, getCurrentUser } = await import('aws-amplify/auth')\n const { Amplify } = await import('aws-amplify')\n\n Amplify.configure({\n Auth: {\n Cognito: {\n userPoolId: config.cognito.userPoolId,\n userPoolClientId: config.cognito.clientId,\n loginWith: {\n oauth: {\n domain: config.cognito.domain.replace('https://', ''),\n scopes: (config.cognito.scope || 'openid profile email').split(' '),\n redirectSignIn: [window.location.origin],\n redirectSignOut: [window.location.origin],\n responseType: 'code'\n }\n }\n }\n }\n })\n\n return {\n login: async () => { await signInWithRedirect() },\n logout: async () => { await signOut() },\n getUser: async () => {\n try {\n const user = await getCurrentUser()\n return { id: user.userId, email: user.signInDetails?.loginId || '', name: user.username }\n } catch { return undefined }\n },\n getTokenSilently: async () => {\n const session = await fetchAuthSession()\n const token = session.tokens?.accessToken?.toString()\n if (!token) throw new Error('No token available')\n return token\n },\n isAuthenticated: async () => {\n try {\n await getCurrentUser()\n return true\n } catch { return false }\n },\n\n async signIn(email: string, password: string) {\n const { signIn } = await import('aws-amplify/auth')\n await signIn({ username: email, password })\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const { signUp } = await import('aws-amplify/auth')\n await signUp({\n username: email,\n password,\n options: { userAttributes: { email, ...metadata } }\n })\n },\n\n async forgotPassword(email: string) {\n const { resetPassword } = await import('aws-amplify/auth')\n await resetPassword({ username: email })\n },\n\n async resetPassword(code: string, newPassword: string) {\n const { confirmResetPassword } = await import('aws-amplify/auth')\n // Note: caller must track the username from the forgotPassword call\n await confirmResetPassword({ username: '', confirmationCode: code, newPassword })\n }\n }\n }\n\n case 'none':\n return {\n login: async () => {},\n logout: async () => {},\n getUser: async () => undefined,\n getTokenSilently: async () => 'none',\n isAuthenticated: async () => true\n }\n\n default:\n throw new Error(`Unknown auth provider: ${config.provider}`)\n }\n}\n\n/**\n * Wrap an AuthClient into the reactive AuthService interface.\n */\nexport function createAuthService(client: AuthClient): AuthService {\n let user: User | null = null\n const listeners: Array<(user: User | null) => void> = []\n\n function notifyListeners() {\n listeners.forEach(fn => { try { fn(user) } catch { /* */ } })\n }\n\n return {\n get user() { return user },\n get isAuthenticated() { return !!user },\n\n async getToken() {\n return client.getTokenSilently()\n },\n\n async login(options) {\n await client.login(options)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async logout(options) {\n await client.logout(options)\n user = null\n notifyListeners()\n },\n\n async signIn(email: string, password: string) {\n if (!client.signIn) throw new Error('signIn not supported by this auth provider')\n await client.signIn(email, password)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n if (!client.signUp) throw new Error('signUp not supported by this auth provider')\n await client.signUp(email, password, metadata)\n },\n\n async forgotPassword(email: string) {\n if (!client.forgotPassword) throw new Error('forgotPassword not supported by this auth provider')\n await client.forgotPassword(email)\n },\n\n async resetPassword(code: string, newPassword: string) {\n if (!client.resetPassword) throw new Error('resetPassword not supported by this auth provider')\n await client.resetPassword(code, newPassword)\n },\n\n onChange(callback) {\n if (listeners.length >= MAX_LISTENERS) {\n console.warn('[Foundation SDK] Auth listener limit reached.')\n return () => {}\n }\n listeners.push(callback)\n return () => {\n const idx = listeners.indexOf(callback)\n if (idx > -1) listeners.splice(idx, 1)\n }\n },\n\n /** @internal Initialize user state from auth client */\n async _initUser() {\n const authenticated = await client.isAuthenticated()\n if (authenticated) {\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n }\n }\n } as AuthService & { _initUser(): Promise<void> }\n}\n","export interface JwtClaims {\n sub: string\n apiBaseUrl: string\n accountBaseUrl: string\n websocketBaseUrl: string\n userId: string\n namespace?: string\n}\n\nexport function parseJwt(token: string): JwtClaims {\n if (!token) {\n throw new Error('Token parsing failed: Missing auth token')\n }\n\n try {\n // Auth0 tokens can have query params appended: \"jwt?param=value\"\n const [jwtPart, queryPart] = token.split('?')\n\n const parts = jwtPart.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n const payloadStr = atob(parts[1])\n const jwtPayload = JSON.parse(payloadStr)\n\n // Merge query params if present\n if (queryPart) {\n const params = new URLSearchParams(queryPart)\n params.forEach((value, key) => {\n jwtPayload[key] = value\n })\n }\n\n const apiBaseUrl = jwtPayload['BaseApplication/apiBaseUrl']\n if (!apiBaseUrl) {\n throw new Error('Token missing apiBaseUrl')\n }\n\n const websocketBaseUrl = jwtPayload['BaseApplication/websocketBaseUrl'] || ''\n const accountBaseUrl = jwtPayload['BaseApplication/accountBaseUrl'] || apiBaseUrl\n\n return {\n sub: jwtPayload.sub || '',\n apiBaseUrl,\n accountBaseUrl,\n websocketBaseUrl,\n userId: jwtPayload['BaseApplication/userId'] || '',\n namespace: jwtPayload['BaseApplication/namespace']\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith('Token')) {\n throw err\n }\n const message = err instanceof Error ? err.message : 'Failed to parse token'\n throw new Error(`Token parsing failed: ${message}`)\n }\n}\n","/**\n * Foundation SDK — typed API client for the Foundation platform.\n *\n * One input: a config URL. The SDK fetches it, discovers auth, API URLs,\n * features, plans, theme, connectors — everything. Self-configuring.\n */\nimport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService,\n EntityChangeEvent,\n User\n} from './types'\nimport { createHttpClient, unwrapResponse, type HttpClient } from './http'\nimport { createAuthClient, createAuthService, type AuthProviderConfig } from './auth'\nimport { parseJwt } from './jwt'\n\nexport async function createFoundation(options: FoundationConfig): Promise<Foundation> {\n // 1. Resolve config URL — foundation-env.json wins if it exists (deployed env)\n let configUrl = options.configUrl\n let resolvedAppId = options.appId\n let resolvedTenantId = options.tenantId\n\n try {\n const envResponse = await fetch('/foundation-env.json')\n if (envResponse.ok) {\n const env = await envResponse.json()\n if (env.configUrl) {\n configUrl = env.configUrl\n resolvedAppId = env.applicationId || resolvedAppId\n resolvedTenantId = env.applicationTenant || resolvedTenantId\n }\n }\n } catch { /* no env file — use passed options */ }\n\n if (!configUrl) {\n throw new Error('No configUrl provided and /foundation-env.json not found')\n }\n\n // 2. Fetch public config\n const configHeaders: Record<string, string> = { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }\n if (resolvedAppId) configHeaders['X-Foundation-Mvp-Application-Id'] = resolvedAppId\n if (resolvedTenantId) configHeaders['X-Foundation-Mvp-Tenant-Id'] = resolvedTenantId\n\n const publicConfigResponse = await fetch(configUrl, { headers: configHeaders })\n if (!publicConfigResponse.ok) {\n throw new Error(`Failed to fetch config: ${publicConfigResponse.statusText}`)\n }\n const rawPublicConfig = await publicConfigResponse.json()\n const publicConfig = rawPublicConfig.data ?? rawPublicConfig\n\n // 2. Set up auth\n const authConfig: AuthProviderConfig = publicConfig.auth || { provider: 'none' }\n const authClient = options.auth || await createAuthClient(authConfig)\n const authServiceRaw = createAuthService(authClient)\n const authService = authServiceRaw as AuthService & { _initUser(): Promise<void> }\n await authService._initUser()\n\n // 3. Determine API URLs\n let apiBaseUrl: string\n let accountBaseUrl: string\n\n if (options.baseUrl) {\n // Explicit override (e.g. '/api' with a dev proxy)\n apiBaseUrl = options.baseUrl\n accountBaseUrl = options.baseUrl\n } else if (authConfig.apiUrls?.apiBaseUrl) {\n // API URLs from public config (no-auth mode or explicit)\n apiBaseUrl = authConfig.apiUrls.apiBaseUrl\n accountBaseUrl = authConfig.apiUrls.accountBaseUrl || apiBaseUrl\n } else {\n // API URLs from JWT token\n const token = await authClient.getTokenSilently()\n const claims = parseJwt(token)\n apiBaseUrl = claims.apiBaseUrl\n accountBaseUrl = claims.accountBaseUrl\n }\n\n // 4. Create HTTP client\n const appId = resolvedAppId || publicConfig.app?.id || publicConfig.tenant?.identifier || ''\n const tenantId = resolvedTenantId || publicConfig.tenant?.identifier || ''\n const version = publicConfig.app?.version || publicConfig.core?.version || '0.0.0'\n\n const http = createHttpClient({\n appId,\n tenantId,\n version,\n getToken: () => authClient.getTokenSilently()\n })\n\n // 5. Fetch backend config (authenticated)\n let backendConfig: Record<string, unknown> = {}\n try {\n const cfg = await http.request(apiBaseUrl, '/api/v1/config/init', 'GET')\n backendConfig = (cfg || {}) as Record<string, unknown>\n } catch (err) {\n console.warn('[Foundation SDK] Backend config fetch failed:', err)\n }\n\n // 6. Merge configs\n const mergedConfig = { ...publicConfig, ...backendConfig }\n\n // Determine namespace from JWT if available\n let namespace = ''\n try {\n const token = await authClient.getTokenSilently()\n if (token && token !== 'none') {\n const claims = parseJwt(token)\n namespace = claims.namespace || ''\n }\n } catch { /* no token yet */ }\n\n // 7. Build config service\n const config: FullConfig = {\n get app() {\n const app = mergedConfig.app as Record<string, unknown> || {}\n return {\n id: (app.id || appId) as string,\n name: (app.name || '') as string,\n version: (app.version || version) as string,\n environment: (app.environment || '') as string,\n ...app\n }\n },\n get features() { return (mergedConfig.features || {}) as Record<string, unknown> },\n get plans() { return (mergedConfig.plans || []) as unknown[] },\n get theme() {\n const theme = mergedConfig.theme as Record<string, unknown> || {}\n return {\n colors: (theme.colors || {}) as Record<string, string>,\n dark: (theme.dark || {}) as Record<string, string>,\n defaultColorScheme: theme.defaultColorScheme as string | undefined\n }\n },\n get connectors() { return (mergedConfig.connectors || {}) as Record<string, unknown> },\n get resources() { return (mergedConfig.resources || {}) as Record<string, string> },\n get auth() {\n const { provider, ...rest } = authConfig\n return { provider, ...rest } as { provider: string; [key: string]: unknown }\n },\n get raw() { return mergedConfig }\n }\n\n // 8. Build services\n const db = createDbService(http, apiBaseUrl)\n const files = createFilesService(http, apiBaseUrl, namespace)\n const account = createAccountService(http, accountBaseUrl)\n const integration = createIntegrationService(http, apiBaseUrl, accountBaseUrl, namespace)\n const openapi = createOpenApiService(http, apiBaseUrl)\n const log = createLogService()\n\n // Entity change listeners (WebSocket support is future)\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const foundation: Foundation = {\n get ready() { return Promise.resolve() },\n get isReady() { return true },\n auth: authService,\n db,\n files,\n integration,\n account,\n config,\n openapi,\n log,\n on(event, callback) {\n if (event === 'entity.changed') {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n }\n return () => {}\n }\n }\n\n return foundation\n}\n\n// --- Service factories ---\n\nfunction createDbService(http: HttpClient, apiBase: string): DbService {\n return {\n async list(entity, options = {}) {\n const { filters, limit, cursor, orderBy, orderDir } = options\n const params: Record<string, unknown> = { ...filters }\n if (limit) params.limit = limit\n if (cursor) params.next = cursor\n if (orderBy) params.orderBy = orderBy\n if (orderDir) params.orderDir = orderDir\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params }) as Promise<any>\n },\n async get(entity, id) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params: { id } }) as Promise<any>\n },\n async create(entity, data) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n },\n async update(entity, id, updates) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: { id, ...updates } }) as Promise<any>\n },\n async save(entity, data) {\n try {\n return await http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: data }) as Promise<any>\n } catch {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n }\n },\n async delete(entity, id) {\n await http.request(apiBase, `/api/v1/core/${entity}`, 'DELETE', { body: { id } })\n }\n }\n}\n\nfunction createFilesService(http: HttpClient, apiBase: string, namespace: string): FilesService {\n return {\n async initiate(options) {\n return http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { ...options, __namespace: namespace }\n }) as Promise<any>\n },\n async upload(options) {\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n fileData = await options.file.arrayBuffer()\n }\n\n const uploadData = await http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { name: options.name, contentType: options.contentType, contentLength: fileData.byteLength, sha256: options.sha256, __namespace: namespace }\n }) as { id: string; name: string; signedUrl: string; signedData: Record<string, string> }\n\n if (!uploadData.signedUrl || !uploadData.signedData) {\n throw new Error('Missing signedUrl or signedData in response')\n }\n\n const formData = new FormData()\n Object.entries(uploadData.signedData).forEach(([key, value]) => {\n formData.append(key, value)\n })\n formData.append('file', new Blob([fileData], { type: options.contentType }), options.name)\n\n const s3Response = await fetch(uploadData.signedUrl, { method: 'POST', body: formData })\n if (s3Response.status !== 204) {\n throw new Error(`S3 upload failed: ${s3Response.status}`)\n }\n\n return { id: uploadData.id, name: uploadData.name, status: 'uploaded', s3UploadComplete: true }\n },\n async get(fileId) {\n return http.request(apiBase, '/api/v1/core/files', 'GET', {\n params: { id: fileId, __namespace: namespace }\n }) as Promise<any>\n },\n async delete(fileId) {\n await http.request(apiBase, `/api/v1/core/files/${fileId}`, 'DELETE')\n },\n async list(options = {}) {\n const params: Record<string, unknown> = { __namespace: namespace }\n if (options.limit) params.limit = options.limit\n if (options.cursor) params.cursor = options.cursor\n const result = await http.request(apiBase, '/api/v1/core/files', 'GET', { params }) as {\n items?: unknown[]; next?: string\n }\n return { items: result?.items || [], nextCursor: result?.next } as any\n }\n }\n}\n\nfunction createAccountService(http: HttpClient, accountBase: string): AccountService {\n return {\n async get() {\n return http.request(accountBase, '/api/v1/accounts/account', 'GET') as Promise<any>\n },\n async update(data) {\n await http.request(accountBase, '/api/v1/accounts/account', 'PUT', { body: { user: data } })\n },\n async usage() {\n return http.request(accountBase, '/api/v1/accounts/account/usage', 'GET') as Promise<any>\n },\n async resendVerification() {\n await http.request(accountBase, '/api/v1/accounts/account/resend-verification', 'POST')\n }\n }\n}\n\nfunction createIntegrationService(http: HttpClient, apiBase: string, accountBase: string, namespace: string): IntegrationService {\n const service: IntegrationService = {\n async list() {\n return http.request(apiBase, '/api/v1/config/connectors', 'GET') as Promise<any>\n },\n async connections() {\n return http.request(apiBase, '/api/v1/core/integrations', 'GET', {\n params: { query: 'default', __namespace: namespace }\n }) as Promise<any>\n },\n async all() {\n const [rawCatalog, rawConnections] = await Promise.all([\n service.list(),\n service.connections()\n ])\n\n const catalog = (Array.isArray(rawCatalog) ? rawCatalog : (rawCatalog as any)?.items || []) as Integration[]\n const connections = (Array.isArray(rawConnections) ? rawConnections : (rawConnections as any)?.items || []) as IntegrationConnection[]\n\n const bySource = new Map<string, IntegrationConnection[]>()\n for (const conn of connections) {\n const source = conn.source || conn.id\n if (!bySource.has(source)) bySource.set(source, [])\n bySource.get(source)!.push(conn)\n }\n\n return catalog.map(item => {\n const conns = bySource.get(item.id) || []\n return {\n ...item,\n connections: conns,\n connected: conns.some(c => c.connected),\n connectionCount: conns.filter(c => c.connected).length\n } as IntegrationDetail\n })\n },\n async status(source) {\n const conns = await service.connections()\n const items = (Array.isArray(conns) ? conns : (conns as any)?.items || []) as IntegrationConnection[]\n const filtered = items.filter(c => c.source === source && c.connected)\n return { connected: filtered.length > 0, connections: filtered }\n },\n async connect(source) {\n return http.request(accountBase, `/api/v1/accounts/integrations/${source}/initialize`, 'POST', {\n body: { __namespace: namespace }\n }) as Promise<any>\n },\n async disconnect(source, configurationId) {\n await http.request(accountBase, `/api/v1/accounts/integrations/${source}/remove`, 'POST', {\n body: { configurationId }\n })\n }\n }\n return service\n}\n\nfunction createOpenApiService(http: HttpClient, apiBase: string): OpenApiService {\n return {\n async get() {\n return http.request(apiBase, '/api/v1/config/openapi', 'GET') as Promise<any>\n }\n }\n}\n\nfunction createLogService(): LogService {\n return {\n info: (message, context) => console.log(`[Foundation] ${message}`, context ?? ''),\n warn: (message, context) => console.warn(`[Foundation] ${message}`, context ?? ''),\n error: (message, context) => console.error(`[Foundation] ${message}`, context ?? ''),\n event: (event, data) => console.log(`[Foundation Event] ${event}`, data ?? '')\n }\n}\n"],"mappings":"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","names":["index_exports","__export","createFoundation","__toCommonJS","unwrapResponse","json","extractError","status","body","errorObj","message","details","detailMessages","d","customMessage","createHttpClient","config","headers","token","request","baseUrl","path","method","options","hdrs","url","searchParams","key","value","qs","fetchOptions","response","rawFetch","createAuthClient","config","createAuth0Client","client","auth0Domain","auth0ClientId","options","user","email","password","response","err","metadata","_code","_newPassword","fetchAuthSession","signInWithRedirect","signOut","getCurrentUser","Amplify","token","signIn","signUp","resetPassword","code","newPassword","confirmResetPassword","createAuthService","listeners","notifyListeners","fn","authUser","callback","idx","parseJwt","token","jwtPart","queryPart","parts","payloadStr","jwtPayload","value","key","apiBaseUrl","websocketBaseUrl","accountBaseUrl","err","message","createFoundation","options","configUrl","resolvedAppId","resolvedTenantId","envResponse","env","configHeaders","publicConfigResponse","rawPublicConfig","publicConfig","authConfig","authClient","createAuthClient","authService","createAuthService","apiBaseUrl","accountBaseUrl","token","claims","parseJwt","appId","tenantId","version","http","createHttpClient","backendConfig","err","mergedConfig","namespace","config","app","theme","provider","rest","db","createDbService","files","createFilesService","account","createAccountService","integration","createIntegrationService","openapi","createOpenApiService","log","createLogService","entityListeners","event","callback","idx","apiBase","entity","filters","limit","cursor","orderBy","orderDir","params","id","data","updates","fileData","uploadData","formData","key","value","s3Response","fileId","result","accountBase","service","rawCatalog","rawConnections","catalog","connections","bySource","conn","source","item","conns","c","filtered","configurationId","message","context"]}
package/dist/index.d.cts CHANGED
@@ -23,7 +23,8 @@ interface EntityChangeEvent {
23
23
  timestamp?: number;
24
24
  }
25
25
  interface FoundationConfig {
26
- configUrl: string;
26
+ /** Backend config endpoint URL. If omitted, reads from /foundation-env.json */
27
+ configUrl?: string;
27
28
  tenantId?: string;
28
29
  appId?: string;
29
30
  /** Override API base URL (e.g. '/api' when using a dev proxy) */
package/dist/index.d.ts CHANGED
@@ -23,7 +23,8 @@ interface EntityChangeEvent {
23
23
  timestamp?: number;
24
24
  }
25
25
  interface FoundationConfig {
26
- configUrl: string;
26
+ /** Backend config endpoint URL. If omitted, reads from /foundation-env.json */
27
+ configUrl?: string;
27
28
  tenantId?: string;
28
29
  appId?: string;
29
30
  /** Override API base URL (e.g. '/api' when using a dev proxy) */
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- function O(e){return e?.response!==void 0?e.response:e?.data!==void 0?e.data:e}function $(e,r){let o=r?.error;if(o){let t=o.message||"Unknown error",n=o.details;if(n?.length){let i=n.map(a=>a.field?`${a.field}: ${a.message}`:a.message).join(", ");t=t?`${t} ${i}`:i}return Object.assign(new Error(t),{code:o.code,type:o.code,details:n,status:e})}let s=r?.data?.message||r?.message;return s?Object.assign(new Error(s),{status:e}):Object.assign(new Error(`HTTP ${e}`),{status:e})}function C(e){function r(t){return{"X-Foundation-Mvp-Application-Id":e.appId,"X-Foundation-Mvp-Tenant-Id":e.tenantId,"X-Foundation-Mvp-Application-Version":e.version,"Content-Type":"application/json",Authorization:`Bearer ${t}`}}async function o(t,n,i,a={}){let u=await e.getToken(),c=r(u),g=`${t}${n}`;if(a.params){let p=new URLSearchParams;for(let[w,y]of Object.entries(a.params))y!=null&&p.set(w,String(y));let h=p.toString();h&&(g+=`?${h}`)}let l={method:i,headers:c};a.body!==void 0&&(l.body=JSON.stringify(a.body));let f=await fetch(g,l);if(!f.ok){let p={};try{p=await f.json()}catch{}throw $(f.status,p)}if(f.status===204)return null;let v=await f.json();return O(v)}async function s(t,n={}){return fetch(t,n)}return{request:o,rawFetch:s,headers:r}}async function k(e){switch(e.provider){case"auth0":{if(!e.auth0)throw new Error("Auth0 config required");let{createAuth0Client:r}=await import("@auth0/auth0-spa-js"),o=await r({domain:e.auth0.domain,clientId:e.auth0.clientId,authorizationParams:{audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email",redirect_uri:window.location.origin},useRefreshTokens:!0,cacheLocation:"localstorage"}),s=e.auth0.domain,t=e.auth0.clientId;return{login:n=>o.loginWithRedirect(n),logout:n=>o.logout({logoutParams:{returnTo:window.location.origin},...n}),getUser:async()=>{let n=await o.getUser();if(n)return{id:n.sub||"",email:n.email||"",name:n.name,picture:n.picture}},getTokenSilently:n=>o.getTokenSilently(n),isAuthenticated:()=>o.isAuthenticated(),async signIn(n,i){let a=await fetch(`https://${s}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"password",client_id:t,username:n,password:i,audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email"})});if(!a.ok){let u=await a.json().catch(()=>({}));throw new Error(u.error_description||u.message||"Sign in failed")}},async signUp(n,i,a){let u=await fetch(`https://${s}/dbconnections/signup`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:t,email:n,password:i,connection:"Username-Password-Authentication",...a})});if(!u.ok){let c=await u.json().catch(()=>({}));throw new Error(c.description||c.message||"Sign up failed")}},async forgotPassword(n){let i=await fetch(`https://${s}/dbconnections/change_password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:t,email:n,connection:"Username-Password-Authentication"})});if(!i.ok){let a=await i.json().catch(()=>({}));throw new Error(a.error_description||a.message||"Password reset request failed")}},async resetPassword(n,i){throw new Error("Auth0 password reset is completed via the email link, not a code")}}}case"cognito":{if(!e.cognito)throw new Error("Cognito config required");let{fetchAuthSession:r,signInWithRedirect:o,signOut:s,getCurrentUser:t}=await import("aws-amplify/auth"),{Amplify:n}=await import("aws-amplify");return n.configure({Auth:{Cognito:{userPoolId:e.cognito.userPoolId,userPoolClientId:e.cognito.clientId,loginWith:{oauth:{domain:e.cognito.domain.replace("https://",""),scopes:(e.cognito.scope||"openid profile email").split(" "),redirectSignIn:[window.location.origin],redirectSignOut:[window.location.origin],responseType:"code"}}}}}),{login:async()=>{await o()},logout:async()=>{await s()},getUser:async()=>{try{let i=await t();return{id:i.userId,email:i.signInDetails?.loginId||"",name:i.username}}catch{return}},getTokenSilently:async()=>{let a=(await r()).tokens?.accessToken?.toString();if(!a)throw new Error("No token available");return a},isAuthenticated:async()=>{try{return await t(),!0}catch{return!1}},async signIn(i,a){let{signIn:u}=await import("aws-amplify/auth");await u({username:i,password:a})},async signUp(i,a,u){let{signUp:c}=await import("aws-amplify/auth");await c({username:i,password:a,options:{userAttributes:{email:i,...u}}})},async forgotPassword(i){let{resetPassword:a}=await import("aws-amplify/auth");await a({username:i})},async resetPassword(i,a){let{confirmResetPassword:u}=await import("aws-amplify/auth");await u({username:"",confirmationCode:i,newPassword:a})}}}case"none":return{login:async()=>{},logout:async()=>{},getUser:async()=>{},getTokenSilently:async()=>"none",isAuthenticated:async()=>!0};default:throw new Error(`Unknown auth provider: ${e.provider}`)}}function A(e){let r=null,o=[];function s(){o.forEach(t=>{try{t(r)}catch{}})}return{get user(){return r},get isAuthenticated(){return!!r},async getToken(){return e.getTokenSilently()},async login(t){await e.login(t);let n=await e.getUser();r=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null,s()},async logout(t){await e.logout(t),r=null,s()},async signIn(t,n){if(!e.signIn)throw new Error("signIn not supported by this auth provider");await e.signIn(t,n);let i=await e.getUser();r=i?{id:i.id,email:i.email,name:i.name,picture:i.picture}:null,s()},async signUp(t,n,i){if(!e.signUp)throw new Error("signUp not supported by this auth provider");await e.signUp(t,n,i)},async forgotPassword(t){if(!e.forgotPassword)throw new Error("forgotPassword not supported by this auth provider");await e.forgotPassword(t)},async resetPassword(t,n){if(!e.resetPassword)throw new Error("resetPassword not supported by this auth provider");await e.resetPassword(t,n)},onChange(t){return o.length>=100?(console.warn("[Foundation SDK] Auth listener limit reached."),()=>{}):(o.push(t),()=>{let n=o.indexOf(t);n>-1&&o.splice(n,1)})},async _initUser(){if(await e.isAuthenticated()){let n=await e.getUser();r=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null}}}}function P(e){if(!e)throw new Error("Token parsing failed: Missing auth token");try{let[r,o]=e.split("?"),s=r.split(".");if(s.length!==3)throw new Error("Invalid JWT format");let t=atob(s[1]),n=JSON.parse(t);o&&new URLSearchParams(o).forEach((g,l)=>{n[l]=g});let i=n["BaseApplication/apiBaseUrl"];if(!i)throw new Error("Token missing apiBaseUrl");let a=n["BaseApplication/websocketBaseUrl"]||"",u=n["BaseApplication/accountBaseUrl"]||i;return{sub:n.sub||"",apiBaseUrl:i,accountBaseUrl:u,websocketBaseUrl:a,userId:n["BaseApplication/userId"]||"",namespace:n["BaseApplication/namespace"]}}catch(r){if(r instanceof Error&&r.message.startsWith("Token"))throw r;let o=r instanceof Error?r.message:"Failed to parse token";throw new Error(`Token parsing failed: ${o}`)}}async function _(e){let r={Accept:"application/json","Cache-Control":"no-cache"};e.appId&&(r["X-Foundation-Mvp-Application-Id"]=e.appId),e.tenantId&&(r["X-Foundation-Mvp-Tenant-Id"]=e.tenantId);let o=await fetch(e.configUrl,{headers:r});if(!o.ok)throw new Error(`Failed to fetch config: ${o.statusText}`);let s=await o.json(),t=s.data??s,n=t.auth||{provider:"none"},i=e.auth||await k(n),u=A(i);await u._initUser();let c,g;if(e.baseUrl)c=e.baseUrl,g=e.baseUrl;else if(n.apiUrls?.apiBaseUrl)c=n.apiUrls.apiBaseUrl,g=n.apiUrls.accountBaseUrl||c;else{let d=await i.getTokenSilently(),m=P(d);c=m.apiBaseUrl,g=m.accountBaseUrl}let l=e.appId||t.app?.id||t.tenant?.identifier||"",f=e.tenantId||t.tenant?.identifier||"",v=t.app?.version||t.core?.version||"0.0.0",p=C({appId:l,tenantId:f,version:v,getToken:()=>i.getTokenSilently()}),h={};try{h=await p.request(c,"/api/v1/config/init","GET")||{}}catch(d){console.warn("[Foundation SDK] Backend config fetch failed:",d)}let w={...t,...h},y="";try{let d=await i.getTokenSilently();d&&d!=="none"&&(y=P(d).namespace||"")}catch{}let I={get app(){let d=w.app||{};return{id:d.id||l,name:d.name||"",version:d.version||v,environment:d.environment||"",...d}},get features(){return w.features||{}},get plans(){return w.plans||[]},get theme(){let d=w.theme||{};return{colors:d.colors||{},dark:d.dark||{},defaultColorScheme:d.defaultColorScheme}},get connectors(){return w.connectors||{}},get resources(){return w.resources||{}},get auth(){let{provider:d,...m}=n;return{provider:d,...m}},get raw(){return w}},T=x(p,c),E=D(p,c,y),b=B(p,g),R=j(p,c,g,y),F=L(p,c),q=H(),S=[];return{get ready(){return Promise.resolve()},get isReady(){return!0},auth:u,db:T,files:E,integration:R,account:b,config:I,openapi:F,log:q,on(d,m){return d==="entity.changed"?(S.push(m),()=>{let U=S.indexOf(m);U>-1&&S.splice(U,1)}):()=>{}}}}function x(e,r){return{async list(o,s={}){let{filters:t,limit:n,cursor:i,orderBy:a,orderDir:u}=s,c={...t};return n&&(c.limit=n),i&&(c.next=i),a&&(c.orderBy=a),u&&(c.orderDir=u),e.request(r,`/api/v1/core/${o}`,"GET",{params:c})},async get(o,s){return e.request(r,`/api/v1/core/${o}`,"GET",{params:{id:s}})},async create(o,s){return e.request(r,`/api/v1/core/${o}`,"POST",{body:s})},async update(o,s,t){return e.request(r,`/api/v1/core/${o}`,"PUT",{body:{id:s,...t}})},async save(o,s){try{return await e.request(r,`/api/v1/core/${o}`,"PUT",{body:s})}catch{return e.request(r,`/api/v1/core/${o}`,"POST",{body:s})}},async delete(o,s){await e.request(r,`/api/v1/core/${o}`,"DELETE",{body:{id:s}})}}}function D(e,r,o){return{async initiate(s){return e.request(r,"/api/v1/core/upload","POST",{body:{...s,__namespace:o}})},async upload(s){let t;s.file instanceof ArrayBuffer?t=s.file:t=await s.file.arrayBuffer();let n=await e.request(r,"/api/v1/core/upload","POST",{body:{name:s.name,contentType:s.contentType,contentLength:t.byteLength,sha256:s.sha256,__namespace:o}});if(!n.signedUrl||!n.signedData)throw new Error("Missing signedUrl or signedData in response");let i=new FormData;Object.entries(n.signedData).forEach(([u,c])=>{i.append(u,c)}),i.append("file",new Blob([t],{type:s.contentType}),s.name);let a=await fetch(n.signedUrl,{method:"POST",body:i});if(a.status!==204)throw new Error(`S3 upload failed: ${a.status}`);return{id:n.id,name:n.name,status:"uploaded",s3UploadComplete:!0}},async get(s){return e.request(r,"/api/v1/core/files","GET",{params:{id:s,__namespace:o}})},async delete(s){await e.request(r,`/api/v1/core/files/${s}`,"DELETE")},async list(s={}){let t={__namespace:o};s.limit&&(t.limit=s.limit),s.cursor&&(t.cursor=s.cursor);let n=await e.request(r,"/api/v1/core/files","GET",{params:t});return{items:n?.items||[],nextCursor:n?.next}}}}function B(e,r){return{async get(){return e.request(r,"/api/v1/accounts/account","GET")},async update(o){await e.request(r,"/api/v1/accounts/account","PUT",{body:{user:o}})},async usage(){return e.request(r,"/api/v1/accounts/account/usage","GET")},async resendVerification(){await e.request(r,"/api/v1/accounts/account/resend-verification","POST")}}}function j(e,r,o,s){let t={async list(){return e.request(r,"/api/v1/config/connectors","GET")},async connections(){return e.request(r,"/api/v1/core/integrations","GET",{params:{query:"default",__namespace:s}})},async all(){let[n,i]=await Promise.all([t.list(),t.connections()]),a=Array.isArray(n)?n:n?.items||[],u=Array.isArray(i)?i:i?.items||[],c=new Map;for(let g of u){let l=g.source||g.id;c.has(l)||c.set(l,[]),c.get(l).push(g)}return a.map(g=>{let l=c.get(g.id)||[];return{...g,connections:l,connected:l.some(f=>f.connected),connectionCount:l.filter(f=>f.connected).length}})},async status(n){let i=await t.connections(),u=(Array.isArray(i)?i:i?.items||[]).filter(c=>c.source===n&&c.connected);return{connected:u.length>0,connections:u}},async connect(n){return e.request(o,`/api/v1/accounts/integrations/${n}/initialize`,"POST",{body:{__namespace:s}})},async disconnect(n,i){await e.request(o,`/api/v1/accounts/integrations/${n}/remove`,"POST",{body:{configurationId:i}})}};return t}function L(e,r){return{async get(){return e.request(r,"/api/v1/config/openapi","GET")}}}function H(){return{info:(e,r)=>console.log(`[Foundation] ${e}`,r??""),warn:(e,r)=>console.warn(`[Foundation] ${e}`,r??""),error:(e,r)=>console.error(`[Foundation] ${e}`,r??""),event:(e,r)=>console.log(`[Foundation Event] ${e}`,r??"")}}export{_ as createFoundation};
1
+ function x(e){return e?.response!==void 0?e.response:e?.data!==void 0?e.data:e}function D(e,t){let o=t?.error;if(o){let i=o.message||"Unknown error",n=o.details;if(n?.length){let s=n.map(a=>a.field?`${a.field}: ${a.message}`:a.message).join(", ");i=i?`${i} ${s}`:s}return Object.assign(new Error(i),{code:o.code,type:o.code,details:n,status:e})}let r=t?.data?.message||t?.message;return r?Object.assign(new Error(r),{status:e}):Object.assign(new Error(`HTTP ${e}`),{status:e})}function T(e){function t(i){return{"X-Foundation-Mvp-Application-Id":e.appId,"X-Foundation-Mvp-Tenant-Id":e.tenantId,"X-Foundation-Mvp-Application-Version":e.version,"Content-Type":"application/json",Authorization:`Bearer ${i}`}}async function o(i,n,s,a={}){let c=await e.getToken(),u=t(c),f=`${i}${n}`;if(a.params){let m=new URLSearchParams;for(let[S,w]of Object.entries(a.params))w!=null&&m.set(S,String(w));let v=m.toString();v&&(f+=`?${v}`)}let l={method:s,headers:u};a.body!==void 0&&(l.body=JSON.stringify(a.body));let g=await fetch(f,l);if(!g.ok){let m={};try{m=await g.json()}catch{}throw D(g.status,m)}if(g.status===204)return null;let y=await g.json();return x(y)}async function r(i,n={}){return fetch(i,n)}return{request:o,rawFetch:r,headers:t}}async function I(e){switch(e.provider){case"auth0":{if(!e.auth0)throw new Error("Auth0 config required");let{createAuth0Client:t}=await import("@auth0/auth0-spa-js"),o=await t({domain:e.auth0.domain,clientId:e.auth0.clientId,authorizationParams:{audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email",redirect_uri:window.location.origin},useRefreshTokens:!0,cacheLocation:"localstorage"}),r=e.auth0.domain,i=e.auth0.clientId;return{login:n=>o.loginWithRedirect(n),logout:n=>o.logout({logoutParams:{returnTo:window.location.origin},...n}),getUser:async()=>{let n=await o.getUser();if(n)return{id:n.sub||"",email:n.email||"",name:n.name,picture:n.picture}},getTokenSilently:n=>o.getTokenSilently(n),isAuthenticated:()=>o.isAuthenticated(),async signIn(n,s){let a=await fetch(`https://${r}/oauth/token`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"password",client_id:i,username:n,password:s,audience:e.auth0.audience,scope:e.auth0.scope||"openid profile email"})});if(!a.ok){let c=await a.json().catch(()=>({}));throw new Error(c.error_description||c.message||"Sign in failed")}},async signUp(n,s,a){let c=await fetch(`https://${r}/dbconnections/signup`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:i,email:n,password:s,connection:"Username-Password-Authentication",...a})});if(!c.ok){let u=await c.json().catch(()=>({}));throw new Error(u.description||u.message||"Sign up failed")}},async forgotPassword(n){let s=await fetch(`https://${r}/dbconnections/change_password`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({client_id:i,email:n,connection:"Username-Password-Authentication"})});if(!s.ok){let a=await s.json().catch(()=>({}));throw new Error(a.error_description||a.message||"Password reset request failed")}},async resetPassword(n,s){throw new Error("Auth0 password reset is completed via the email link, not a code")}}}case"cognito":{if(!e.cognito)throw new Error("Cognito config required");let{fetchAuthSession:t,signInWithRedirect:o,signOut:r,getCurrentUser:i}=await import("aws-amplify/auth"),{Amplify:n}=await import("aws-amplify");return n.configure({Auth:{Cognito:{userPoolId:e.cognito.userPoolId,userPoolClientId:e.cognito.clientId,loginWith:{oauth:{domain:e.cognito.domain.replace("https://",""),scopes:(e.cognito.scope||"openid profile email").split(" "),redirectSignIn:[window.location.origin],redirectSignOut:[window.location.origin],responseType:"code"}}}}}),{login:async()=>{await o()},logout:async()=>{await r()},getUser:async()=>{try{let s=await i();return{id:s.userId,email:s.signInDetails?.loginId||"",name:s.username}}catch{return}},getTokenSilently:async()=>{let a=(await t()).tokens?.accessToken?.toString();if(!a)throw new Error("No token available");return a},isAuthenticated:async()=>{try{return await i(),!0}catch{return!1}},async signIn(s,a){let{signIn:c}=await import("aws-amplify/auth");await c({username:s,password:a})},async signUp(s,a,c){let{signUp:u}=await import("aws-amplify/auth");await u({username:s,password:a,options:{userAttributes:{email:s,...c}}})},async forgotPassword(s){let{resetPassword:a}=await import("aws-amplify/auth");await a({username:s})},async resetPassword(s,a){let{confirmResetPassword:c}=await import("aws-amplify/auth");await c({username:"",confirmationCode:s,newPassword:a})}}}case"none":return{login:async()=>{},logout:async()=>{},getUser:async()=>{},getTokenSilently:async()=>"none",isAuthenticated:async()=>!0};default:throw new Error(`Unknown auth provider: ${e.provider}`)}}function E(e){let t=null,o=[];function r(){o.forEach(i=>{try{i(t)}catch{}})}return{get user(){return t},get isAuthenticated(){return!!t},async getToken(){return e.getTokenSilently()},async login(i){await e.login(i);let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null,r()},async logout(i){await e.logout(i),t=null,r()},async signIn(i,n){if(!e.signIn)throw new Error("signIn not supported by this auth provider");await e.signIn(i,n);let s=await e.getUser();t=s?{id:s.id,email:s.email,name:s.name,picture:s.picture}:null,r()},async signUp(i,n,s){if(!e.signUp)throw new Error("signUp not supported by this auth provider");await e.signUp(i,n,s)},async forgotPassword(i){if(!e.forgotPassword)throw new Error("forgotPassword not supported by this auth provider");await e.forgotPassword(i)},async resetPassword(i,n){if(!e.resetPassword)throw new Error("resetPassword not supported by this auth provider");await e.resetPassword(i,n)},onChange(i){return o.length>=100?(console.warn("[Foundation SDK] Auth listener limit reached."),()=>{}):(o.push(i),()=>{let n=o.indexOf(i);n>-1&&o.splice(n,1)})},async _initUser(){if(await e.isAuthenticated()){let n=await e.getUser();t=n?{id:n.id,email:n.email,name:n.name,picture:n.picture}:null}}}}function C(e){if(!e)throw new Error("Token parsing failed: Missing auth token");try{let[t,o]=e.split("?"),r=t.split(".");if(r.length!==3)throw new Error("Invalid JWT format");let i=atob(r[1]),n=JSON.parse(i);o&&new URLSearchParams(o).forEach((f,l)=>{n[l]=f});let s=n["BaseApplication/apiBaseUrl"];if(!s)throw new Error("Token missing apiBaseUrl");let a=n["BaseApplication/websocketBaseUrl"]||"",c=n["BaseApplication/accountBaseUrl"]||s;return{sub:n.sub||"",apiBaseUrl:s,accountBaseUrl:c,websocketBaseUrl:a,userId:n["BaseApplication/userId"]||"",namespace:n["BaseApplication/namespace"]}}catch(t){if(t instanceof Error&&t.message.startsWith("Token"))throw t;let o=t instanceof Error?t.message:"Failed to parse token";throw new Error(`Token parsing failed: ${o}`)}}async function j(e){let t=e.configUrl,o=e.appId,r=e.tenantId;try{let d=await fetch("/foundation-env.json");if(d.ok){let p=await d.json();p.configUrl&&(t=p.configUrl,o=p.applicationId||o,r=p.applicationTenant||r)}}catch{}if(!t)throw new Error("No configUrl provided and /foundation-env.json not found");let i={Accept:"application/json","Cache-Control":"no-cache"};o&&(i["X-Foundation-Mvp-Application-Id"]=o),r&&(i["X-Foundation-Mvp-Tenant-Id"]=r);let n=await fetch(t,{headers:i});if(!n.ok)throw new Error(`Failed to fetch config: ${n.statusText}`);let s=await n.json(),a=s.data??s,c=a.auth||{provider:"none"},u=e.auth||await I(c),l=E(u);await l._initUser();let g,y;if(e.baseUrl)g=e.baseUrl,y=e.baseUrl;else if(c.apiUrls?.apiBaseUrl)g=c.apiUrls.apiBaseUrl,y=c.apiUrls.accountBaseUrl||g;else{let d=await u.getTokenSilently(),p=C(d);g=p.apiBaseUrl,y=p.accountBaseUrl}let m=o||a.app?.id||a.tenant?.identifier||"",v=r||a.tenant?.identifier||"",S=a.app?.version||a.core?.version||"0.0.0",w=T({appId:m,tenantId:v,version:S,getToken:()=>u.getTokenSilently()}),k={};try{k=await w.request(g,"/api/v1/config/init","GET")||{}}catch(d){console.warn("[Foundation SDK] Backend config fetch failed:",d)}let h={...a,...k},P="";try{let d=await u.getTokenSilently();d&&d!=="none"&&(P=C(d).namespace||"")}catch{}let b={get app(){let d=h.app||{};return{id:d.id||m,name:d.name||"",version:d.version||S,environment:d.environment||"",...d}},get features(){return h.features||{}},get plans(){return h.plans||[]},get theme(){let d=h.theme||{};return{colors:d.colors||{},dark:d.dark||{},defaultColorScheme:d.defaultColorScheme}},get connectors(){return h.connectors||{}},get resources(){return h.resources||{}},get auth(){let{provider:d,...p}=c;return{provider:d,...p}},get raw(){return h}},R=B(w,g),F=L(w,g,P),q=H(w,y),O=M(w,g,y,P),$=G(w,g),_=J(),U=[];return{get ready(){return Promise.resolve()},get isReady(){return!0},auth:l,db:R,files:F,integration:O,account:q,config:b,openapi:$,log:_,on(d,p){return d==="entity.changed"?(U.push(p),()=>{let A=U.indexOf(p);A>-1&&U.splice(A,1)}):()=>{}}}}function B(e,t){return{async list(o,r={}){let{filters:i,limit:n,cursor:s,orderBy:a,orderDir:c}=r,u={...i};return n&&(u.limit=n),s&&(u.next=s),a&&(u.orderBy=a),c&&(u.orderDir=c),e.request(t,`/api/v1/core/${o}`,"GET",{params:u})},async get(o,r){return e.request(t,`/api/v1/core/${o}`,"GET",{params:{id:r}})},async create(o,r){return e.request(t,`/api/v1/core/${o}`,"POST",{body:r})},async update(o,r,i){return e.request(t,`/api/v1/core/${o}`,"PUT",{body:{id:r,...i}})},async save(o,r){try{return await e.request(t,`/api/v1/core/${o}`,"PUT",{body:r})}catch{return e.request(t,`/api/v1/core/${o}`,"POST",{body:r})}},async delete(o,r){await e.request(t,`/api/v1/core/${o}`,"DELETE",{body:{id:r}})}}}function L(e,t,o){return{async initiate(r){return e.request(t,"/api/v1/core/upload","POST",{body:{...r,__namespace:o}})},async upload(r){let i;r.file instanceof ArrayBuffer?i=r.file:i=await r.file.arrayBuffer();let n=await e.request(t,"/api/v1/core/upload","POST",{body:{name:r.name,contentType:r.contentType,contentLength:i.byteLength,sha256:r.sha256,__namespace:o}});if(!n.signedUrl||!n.signedData)throw new Error("Missing signedUrl or signedData in response");let s=new FormData;Object.entries(n.signedData).forEach(([c,u])=>{s.append(c,u)}),s.append("file",new Blob([i],{type:r.contentType}),r.name);let a=await fetch(n.signedUrl,{method:"POST",body:s});if(a.status!==204)throw new Error(`S3 upload failed: ${a.status}`);return{id:n.id,name:n.name,status:"uploaded",s3UploadComplete:!0}},async get(r){return e.request(t,"/api/v1/core/files","GET",{params:{id:r,__namespace:o}})},async delete(r){await e.request(t,`/api/v1/core/files/${r}`,"DELETE")},async list(r={}){let i={__namespace:o};r.limit&&(i.limit=r.limit),r.cursor&&(i.cursor=r.cursor);let n=await e.request(t,"/api/v1/core/files","GET",{params:i});return{items:n?.items||[],nextCursor:n?.next}}}}function H(e,t){return{async get(){return e.request(t,"/api/v1/accounts/account","GET")},async update(o){await e.request(t,"/api/v1/accounts/account","PUT",{body:{user:o}})},async usage(){return e.request(t,"/api/v1/accounts/account/usage","GET")},async resendVerification(){await e.request(t,"/api/v1/accounts/account/resend-verification","POST")}}}function M(e,t,o,r){let i={async list(){return e.request(t,"/api/v1/config/connectors","GET")},async connections(){return e.request(t,"/api/v1/core/integrations","GET",{params:{query:"default",__namespace:r}})},async all(){let[n,s]=await Promise.all([i.list(),i.connections()]),a=Array.isArray(n)?n:n?.items||[],c=Array.isArray(s)?s:s?.items||[],u=new Map;for(let f of c){let l=f.source||f.id;u.has(l)||u.set(l,[]),u.get(l).push(f)}return a.map(f=>{let l=u.get(f.id)||[];return{...f,connections:l,connected:l.some(g=>g.connected),connectionCount:l.filter(g=>g.connected).length}})},async status(n){let s=await i.connections(),c=(Array.isArray(s)?s:s?.items||[]).filter(u=>u.source===n&&u.connected);return{connected:c.length>0,connections:c}},async connect(n){return e.request(o,`/api/v1/accounts/integrations/${n}/initialize`,"POST",{body:{__namespace:r}})},async disconnect(n,s){await e.request(o,`/api/v1/accounts/integrations/${n}/remove`,"POST",{body:{configurationId:s}})}};return i}function G(e,t){return{async get(){return e.request(t,"/api/v1/config/openapi","GET")}}}function J(){return{info:(e,t)=>console.log(`[Foundation] ${e}`,t??""),warn:(e,t)=>console.warn(`[Foundation] ${e}`,t??""),error:(e,t)=>console.error(`[Foundation] ${e}`,t??""),event:(e,t)=>console.log(`[Foundation Event] ${e}`,t??"")}}export{j as createFoundation};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts","../src/auth.ts","../src/jwt.ts","../src/foundation.ts"],"sourcesContent":["/**\n * HTTP layer for Foundation API calls.\n * Handles request construction, response unwrapping, and error extraction.\n */\n\n/**\n * Unwrap backend response envelope.\n * The API wraps responses in { response: ... } or { data: ... }.\n */\nexport function unwrapResponse(json: Record<string, unknown>): unknown {\n if (json?.response !== undefined) return json.response\n if (json?.data !== undefined) return json.data\n return json\n}\n\n/**\n * Extract a meaningful error from a failed API response.\n */\nexport function extractError(status: number, body: Record<string, unknown>): Error {\n const errorObj = body?.error as Record<string, unknown> | undefined\n\n if (errorObj) {\n let message = errorObj.message as string || 'Unknown error'\n const details = errorObj.details as Array<{ field?: string; message?: string }> | undefined\n if (details?.length) {\n const detailMessages = details\n .map(d => d.field ? `${d.field}: ${d.message}` : d.message)\n .join(', ')\n message = message ? `${message} ${detailMessages}` : detailMessages\n }\n return Object.assign(new Error(message), {\n code: errorObj.code,\n type: errorObj.code,\n details,\n status\n })\n }\n\n const customMessage = (body?.data as Record<string, unknown>)?.message || body?.message\n if (customMessage) {\n return Object.assign(new Error(customMessage as string), { status })\n }\n\n return Object.assign(new Error(`HTTP ${status}`), { status })\n}\n\nexport interface HttpClientConfig {\n appId: string\n tenantId: string\n version: string\n getToken: () => Promise<string>\n}\n\nexport function createHttpClient(config: HttpClientConfig) {\n function headers(token: string): Record<string, string> {\n return {\n 'X-Foundation-Mvp-Application-Id': config.appId,\n 'X-Foundation-Mvp-Tenant-Id': config.tenantId,\n 'X-Foundation-Mvp-Application-Version': config.version,\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n }\n }\n\n async function request(\n baseUrl: string,\n path: string,\n method: string,\n options: { params?: Record<string, unknown>; body?: unknown } = {}\n ): Promise<unknown> {\n const token = await config.getToken()\n const hdrs = headers(token)\n\n let url = `${baseUrl}${path}`\n if (options.params) {\n const searchParams = new URLSearchParams()\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value))\n }\n }\n const qs = searchParams.toString()\n if (qs) url += `?${qs}`\n }\n\n const fetchOptions: RequestInit = { method, headers: hdrs }\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body)\n }\n\n const response = await fetch(url, fetchOptions)\n\n if (!response.ok) {\n let body: Record<string, unknown> = {}\n try { body = await response.json() } catch { /* no json body */ }\n throw extractError(response.status, body)\n }\n\n if (response.status === 204) return null\n\n const json = await response.json()\n return unwrapResponse(json as Record<string, unknown>)\n }\n\n /** Raw fetch with auth headers but no unwrapping (for S3 uploads etc.) */\n async function rawFetch(url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, options)\n }\n\n return { request, rawFetch, headers }\n}\n\nexport type HttpClient = ReturnType<typeof createHttpClient>\n","/**\n * Auth provider factory.\n * Creates the right auth client based on config (Cognito/Auth0/none).\n * Supports custom auth client override.\n */\nimport type { AuthClient, AuthService, User } from './types'\n\nconst MAX_LISTENERS = 100\n\nexport interface AuthProviderConfig {\n provider: string\n auth0?: { domain: string; clientId: string; audience?: string; scope?: string }\n cognito?: { userPoolId: string; clientId: string; region: string; domain: string; scope?: string }\n apiUrls?: { apiBaseUrl: string; accountBaseUrl?: string; websocketBaseUrl?: string }\n}\n\nexport async function createAuthClient(config: AuthProviderConfig): Promise<AuthClient> {\n switch (config.provider) {\n case 'auth0': {\n if (!config.auth0) throw new Error('Auth0 config required')\n const { createAuth0Client } = await import('@auth0/auth0-spa-js')\n const client = await createAuth0Client({\n domain: config.auth0.domain,\n clientId: config.auth0.clientId,\n authorizationParams: {\n audience: config.auth0.audience,\n scope: config.auth0.scope || 'openid profile email',\n redirect_uri: window.location.origin\n },\n useRefreshTokens: true,\n cacheLocation: 'localstorage'\n })\n\n const auth0Domain = config.auth0.domain\n const auth0ClientId = config.auth0.clientId\n\n return {\n login: (options) => client.loginWithRedirect(options),\n logout: (options) => client.logout({ logoutParams: { returnTo: window.location.origin }, ...options }),\n getUser: async () => {\n const user = await client.getUser()\n if (!user) return undefined\n return { id: user.sub || '', email: user.email || '', name: user.name, picture: user.picture }\n },\n getTokenSilently: (options) => client.getTokenSilently(options),\n isAuthenticated: () => client.isAuthenticated(),\n\n async signIn(email: string, password: string) {\n // Auth0 Resource Owner Password Grant\n const response = await fetch(`https://${auth0Domain}/oauth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'password',\n client_id: auth0ClientId,\n username: email,\n password,\n audience: config.auth0!.audience,\n scope: config.auth0!.scope || 'openid profile email'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Sign in failed')\n }\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n password,\n connection: 'Username-Password-Authentication',\n ...metadata\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.description || err.message || 'Sign up failed')\n }\n },\n\n async forgotPassword(email: string) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/change_password`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n connection: 'Username-Password-Authentication'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Password reset request failed')\n }\n },\n\n async resetPassword(_code: string, _newPassword: string) {\n // Auth0 handles reset via email link, not code-based flow\n throw new Error('Auth0 password reset is completed via the email link, not a code')\n }\n }\n }\n\n case 'cognito': {\n if (!config.cognito) throw new Error('Cognito config required')\n const { fetchAuthSession, signInWithRedirect, signOut, getCurrentUser } = await import('aws-amplify/auth')\n const { Amplify } = await import('aws-amplify')\n\n Amplify.configure({\n Auth: {\n Cognito: {\n userPoolId: config.cognito.userPoolId,\n userPoolClientId: config.cognito.clientId,\n loginWith: {\n oauth: {\n domain: config.cognito.domain.replace('https://', ''),\n scopes: (config.cognito.scope || 'openid profile email').split(' '),\n redirectSignIn: [window.location.origin],\n redirectSignOut: [window.location.origin],\n responseType: 'code'\n }\n }\n }\n }\n })\n\n return {\n login: async () => { await signInWithRedirect() },\n logout: async () => { await signOut() },\n getUser: async () => {\n try {\n const user = await getCurrentUser()\n return { id: user.userId, email: user.signInDetails?.loginId || '', name: user.username }\n } catch { return undefined }\n },\n getTokenSilently: async () => {\n const session = await fetchAuthSession()\n const token = session.tokens?.accessToken?.toString()\n if (!token) throw new Error('No token available')\n return token\n },\n isAuthenticated: async () => {\n try {\n await getCurrentUser()\n return true\n } catch { return false }\n },\n\n async signIn(email: string, password: string) {\n const { signIn } = await import('aws-amplify/auth')\n await signIn({ username: email, password })\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const { signUp } = await import('aws-amplify/auth')\n await signUp({\n username: email,\n password,\n options: { userAttributes: { email, ...metadata } }\n })\n },\n\n async forgotPassword(email: string) {\n const { resetPassword } = await import('aws-amplify/auth')\n await resetPassword({ username: email })\n },\n\n async resetPassword(code: string, newPassword: string) {\n const { confirmResetPassword } = await import('aws-amplify/auth')\n // Note: caller must track the username from the forgotPassword call\n await confirmResetPassword({ username: '', confirmationCode: code, newPassword })\n }\n }\n }\n\n case 'none':\n return {\n login: async () => {},\n logout: async () => {},\n getUser: async () => undefined,\n getTokenSilently: async () => 'none',\n isAuthenticated: async () => true\n }\n\n default:\n throw new Error(`Unknown auth provider: ${config.provider}`)\n }\n}\n\n/**\n * Wrap an AuthClient into the reactive AuthService interface.\n */\nexport function createAuthService(client: AuthClient): AuthService {\n let user: User | null = null\n const listeners: Array<(user: User | null) => void> = []\n\n function notifyListeners() {\n listeners.forEach(fn => { try { fn(user) } catch { /* */ } })\n }\n\n return {\n get user() { return user },\n get isAuthenticated() { return !!user },\n\n async getToken() {\n return client.getTokenSilently()\n },\n\n async login(options) {\n await client.login(options)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async logout(options) {\n await client.logout(options)\n user = null\n notifyListeners()\n },\n\n async signIn(email: string, password: string) {\n if (!client.signIn) throw new Error('signIn not supported by this auth provider')\n await client.signIn(email, password)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n if (!client.signUp) throw new Error('signUp not supported by this auth provider')\n await client.signUp(email, password, metadata)\n },\n\n async forgotPassword(email: string) {\n if (!client.forgotPassword) throw new Error('forgotPassword not supported by this auth provider')\n await client.forgotPassword(email)\n },\n\n async resetPassword(code: string, newPassword: string) {\n if (!client.resetPassword) throw new Error('resetPassword not supported by this auth provider')\n await client.resetPassword(code, newPassword)\n },\n\n onChange(callback) {\n if (listeners.length >= MAX_LISTENERS) {\n console.warn('[Foundation SDK] Auth listener limit reached.')\n return () => {}\n }\n listeners.push(callback)\n return () => {\n const idx = listeners.indexOf(callback)\n if (idx > -1) listeners.splice(idx, 1)\n }\n },\n\n /** @internal Initialize user state from auth client */\n async _initUser() {\n const authenticated = await client.isAuthenticated()\n if (authenticated) {\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n }\n }\n } as AuthService & { _initUser(): Promise<void> }\n}\n","export interface JwtClaims {\n sub: string\n apiBaseUrl: string\n accountBaseUrl: string\n websocketBaseUrl: string\n userId: string\n namespace?: string\n}\n\nexport function parseJwt(token: string): JwtClaims {\n if (!token) {\n throw new Error('Token parsing failed: Missing auth token')\n }\n\n try {\n // Auth0 tokens can have query params appended: \"jwt?param=value\"\n const [jwtPart, queryPart] = token.split('?')\n\n const parts = jwtPart.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n const payloadStr = atob(parts[1])\n const jwtPayload = JSON.parse(payloadStr)\n\n // Merge query params if present\n if (queryPart) {\n const params = new URLSearchParams(queryPart)\n params.forEach((value, key) => {\n jwtPayload[key] = value\n })\n }\n\n const apiBaseUrl = jwtPayload['BaseApplication/apiBaseUrl']\n if (!apiBaseUrl) {\n throw new Error('Token missing apiBaseUrl')\n }\n\n const websocketBaseUrl = jwtPayload['BaseApplication/websocketBaseUrl'] || ''\n const accountBaseUrl = jwtPayload['BaseApplication/accountBaseUrl'] || apiBaseUrl\n\n return {\n sub: jwtPayload.sub || '',\n apiBaseUrl,\n accountBaseUrl,\n websocketBaseUrl,\n userId: jwtPayload['BaseApplication/userId'] || '',\n namespace: jwtPayload['BaseApplication/namespace']\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith('Token')) {\n throw err\n }\n const message = err instanceof Error ? err.message : 'Failed to parse token'\n throw new Error(`Token parsing failed: ${message}`)\n }\n}\n","/**\n * Foundation SDK — typed API client for the Foundation platform.\n *\n * One input: a config URL. The SDK fetches it, discovers auth, API URLs,\n * features, plans, theme, connectors — everything. Self-configuring.\n */\nimport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService,\n EntityChangeEvent,\n User\n} from './types'\nimport { createHttpClient, unwrapResponse, type HttpClient } from './http'\nimport { createAuthClient, createAuthService, type AuthProviderConfig } from './auth'\nimport { parseJwt } from './jwt'\n\nexport async function createFoundation(options: FoundationConfig): Promise<Foundation> {\n // 1. Fetch public config\n const configHeaders: Record<string, string> = { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }\n if (options.appId) configHeaders['X-Foundation-Mvp-Application-Id'] = options.appId\n if (options.tenantId) configHeaders['X-Foundation-Mvp-Tenant-Id'] = options.tenantId\n\n const publicConfigResponse = await fetch(options.configUrl, { headers: configHeaders })\n if (!publicConfigResponse.ok) {\n throw new Error(`Failed to fetch config: ${publicConfigResponse.statusText}`)\n }\n const rawPublicConfig = await publicConfigResponse.json()\n const publicConfig = rawPublicConfig.data ?? rawPublicConfig\n\n // 2. Set up auth\n const authConfig: AuthProviderConfig = publicConfig.auth || { provider: 'none' }\n const authClient = options.auth || await createAuthClient(authConfig)\n const authServiceRaw = createAuthService(authClient)\n const authService = authServiceRaw as AuthService & { _initUser(): Promise<void> }\n await authService._initUser()\n\n // 3. Determine API URLs\n let apiBaseUrl: string\n let accountBaseUrl: string\n\n if (options.baseUrl) {\n // Explicit override (e.g. '/api' with a dev proxy)\n apiBaseUrl = options.baseUrl\n accountBaseUrl = options.baseUrl\n } else if (authConfig.apiUrls?.apiBaseUrl) {\n // API URLs from public config (no-auth mode or explicit)\n apiBaseUrl = authConfig.apiUrls.apiBaseUrl\n accountBaseUrl = authConfig.apiUrls.accountBaseUrl || apiBaseUrl\n } else {\n // API URLs from JWT token\n const token = await authClient.getTokenSilently()\n const claims = parseJwt(token)\n apiBaseUrl = claims.apiBaseUrl\n accountBaseUrl = claims.accountBaseUrl\n }\n\n // 4. Create HTTP client\n const appId = options.appId || publicConfig.app?.id || publicConfig.tenant?.identifier || ''\n const tenantId = options.tenantId || publicConfig.tenant?.identifier || ''\n const version = publicConfig.app?.version || publicConfig.core?.version || '0.0.0'\n\n const http = createHttpClient({\n appId,\n tenantId,\n version,\n getToken: () => authClient.getTokenSilently()\n })\n\n // 5. Fetch backend config (authenticated)\n let backendConfig: Record<string, unknown> = {}\n try {\n const cfg = await http.request(apiBaseUrl, '/api/v1/config/init', 'GET')\n backendConfig = (cfg || {}) as Record<string, unknown>\n } catch (err) {\n console.warn('[Foundation SDK] Backend config fetch failed:', err)\n }\n\n // 6. Merge configs\n const mergedConfig = { ...publicConfig, ...backendConfig }\n\n // Determine namespace from JWT if available\n let namespace = ''\n try {\n const token = await authClient.getTokenSilently()\n if (token && token !== 'none') {\n const claims = parseJwt(token)\n namespace = claims.namespace || ''\n }\n } catch { /* no token yet */ }\n\n // 7. Build config service\n const config: FullConfig = {\n get app() {\n const app = mergedConfig.app as Record<string, unknown> || {}\n return {\n id: (app.id || appId) as string,\n name: (app.name || '') as string,\n version: (app.version || version) as string,\n environment: (app.environment || '') as string,\n ...app\n }\n },\n get features() { return (mergedConfig.features || {}) as Record<string, unknown> },\n get plans() { return (mergedConfig.plans || []) as unknown[] },\n get theme() {\n const theme = mergedConfig.theme as Record<string, unknown> || {}\n return {\n colors: (theme.colors || {}) as Record<string, string>,\n dark: (theme.dark || {}) as Record<string, string>,\n defaultColorScheme: theme.defaultColorScheme as string | undefined\n }\n },\n get connectors() { return (mergedConfig.connectors || {}) as Record<string, unknown> },\n get resources() { return (mergedConfig.resources || {}) as Record<string, string> },\n get auth() {\n const { provider, ...rest } = authConfig\n return { provider, ...rest } as { provider: string; [key: string]: unknown }\n },\n get raw() { return mergedConfig }\n }\n\n // 8. Build services\n const db = createDbService(http, apiBaseUrl)\n const files = createFilesService(http, apiBaseUrl, namespace)\n const account = createAccountService(http, accountBaseUrl)\n const integration = createIntegrationService(http, apiBaseUrl, accountBaseUrl, namespace)\n const openapi = createOpenApiService(http, apiBaseUrl)\n const log = createLogService()\n\n // Entity change listeners (WebSocket support is future)\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const foundation: Foundation = {\n get ready() { return Promise.resolve() },\n get isReady() { return true },\n auth: authService,\n db,\n files,\n integration,\n account,\n config,\n openapi,\n log,\n on(event, callback) {\n if (event === 'entity.changed') {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n }\n return () => {}\n }\n }\n\n return foundation\n}\n\n// --- Service factories ---\n\nfunction createDbService(http: HttpClient, apiBase: string): DbService {\n return {\n async list(entity, options = {}) {\n const { filters, limit, cursor, orderBy, orderDir } = options\n const params: Record<string, unknown> = { ...filters }\n if (limit) params.limit = limit\n if (cursor) params.next = cursor\n if (orderBy) params.orderBy = orderBy\n if (orderDir) params.orderDir = orderDir\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params }) as Promise<any>\n },\n async get(entity, id) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params: { id } }) as Promise<any>\n },\n async create(entity, data) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n },\n async update(entity, id, updates) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: { id, ...updates } }) as Promise<any>\n },\n async save(entity, data) {\n try {\n return await http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: data }) as Promise<any>\n } catch {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n }\n },\n async delete(entity, id) {\n await http.request(apiBase, `/api/v1/core/${entity}`, 'DELETE', { body: { id } })\n }\n }\n}\n\nfunction createFilesService(http: HttpClient, apiBase: string, namespace: string): FilesService {\n return {\n async initiate(options) {\n return http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { ...options, __namespace: namespace }\n }) as Promise<any>\n },\n async upload(options) {\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n fileData = await options.file.arrayBuffer()\n }\n\n const uploadData = await http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { name: options.name, contentType: options.contentType, contentLength: fileData.byteLength, sha256: options.sha256, __namespace: namespace }\n }) as { id: string; name: string; signedUrl: string; signedData: Record<string, string> }\n\n if (!uploadData.signedUrl || !uploadData.signedData) {\n throw new Error('Missing signedUrl or signedData in response')\n }\n\n const formData = new FormData()\n Object.entries(uploadData.signedData).forEach(([key, value]) => {\n formData.append(key, value)\n })\n formData.append('file', new Blob([fileData], { type: options.contentType }), options.name)\n\n const s3Response = await fetch(uploadData.signedUrl, { method: 'POST', body: formData })\n if (s3Response.status !== 204) {\n throw new Error(`S3 upload failed: ${s3Response.status}`)\n }\n\n return { id: uploadData.id, name: uploadData.name, status: 'uploaded', s3UploadComplete: true }\n },\n async get(fileId) {\n return http.request(apiBase, '/api/v1/core/files', 'GET', {\n params: { id: fileId, __namespace: namespace }\n }) as Promise<any>\n },\n async delete(fileId) {\n await http.request(apiBase, `/api/v1/core/files/${fileId}`, 'DELETE')\n },\n async list(options = {}) {\n const params: Record<string, unknown> = { __namespace: namespace }\n if (options.limit) params.limit = options.limit\n if (options.cursor) params.cursor = options.cursor\n const result = await http.request(apiBase, '/api/v1/core/files', 'GET', { params }) as {\n items?: unknown[]; next?: string\n }\n return { items: result?.items || [], nextCursor: result?.next } as any\n }\n }\n}\n\nfunction createAccountService(http: HttpClient, accountBase: string): AccountService {\n return {\n async get() {\n return http.request(accountBase, '/api/v1/accounts/account', 'GET') as Promise<any>\n },\n async update(data) {\n await http.request(accountBase, '/api/v1/accounts/account', 'PUT', { body: { user: data } })\n },\n async usage() {\n return http.request(accountBase, '/api/v1/accounts/account/usage', 'GET') as Promise<any>\n },\n async resendVerification() {\n await http.request(accountBase, '/api/v1/accounts/account/resend-verification', 'POST')\n }\n }\n}\n\nfunction createIntegrationService(http: HttpClient, apiBase: string, accountBase: string, namespace: string): IntegrationService {\n const service: IntegrationService = {\n async list() {\n return http.request(apiBase, '/api/v1/config/connectors', 'GET') as Promise<any>\n },\n async connections() {\n return http.request(apiBase, '/api/v1/core/integrations', 'GET', {\n params: { query: 'default', __namespace: namespace }\n }) as Promise<any>\n },\n async all() {\n const [rawCatalog, rawConnections] = await Promise.all([\n service.list(),\n service.connections()\n ])\n\n const catalog = (Array.isArray(rawCatalog) ? rawCatalog : (rawCatalog as any)?.items || []) as Integration[]\n const connections = (Array.isArray(rawConnections) ? rawConnections : (rawConnections as any)?.items || []) as IntegrationConnection[]\n\n const bySource = new Map<string, IntegrationConnection[]>()\n for (const conn of connections) {\n const source = conn.source || conn.id\n if (!bySource.has(source)) bySource.set(source, [])\n bySource.get(source)!.push(conn)\n }\n\n return catalog.map(item => {\n const conns = bySource.get(item.id) || []\n return {\n ...item,\n connections: conns,\n connected: conns.some(c => c.connected),\n connectionCount: conns.filter(c => c.connected).length\n } as IntegrationDetail\n })\n },\n async status(source) {\n const conns = await service.connections()\n const items = (Array.isArray(conns) ? conns : (conns as any)?.items || []) as IntegrationConnection[]\n const filtered = items.filter(c => c.source === source && c.connected)\n return { connected: filtered.length > 0, connections: filtered }\n },\n async connect(source) {\n return http.request(accountBase, `/api/v1/accounts/integrations/${source}/initialize`, 'POST', {\n body: { __namespace: namespace }\n }) as Promise<any>\n },\n async disconnect(source, configurationId) {\n await http.request(accountBase, `/api/v1/accounts/integrations/${source}/remove`, 'POST', {\n body: { configurationId }\n })\n }\n }\n return service\n}\n\nfunction createOpenApiService(http: HttpClient, apiBase: string): OpenApiService {\n return {\n async get() {\n return http.request(apiBase, '/api/v1/config/openapi', 'GET') as Promise<any>\n }\n }\n}\n\nfunction createLogService(): LogService {\n return {\n info: (message, context) => console.log(`[Foundation] ${message}`, context ?? ''),\n warn: (message, context) => console.warn(`[Foundation] ${message}`, context ?? ''),\n error: (message, context) => console.error(`[Foundation] ${message}`, context ?? ''),\n event: (event, data) => console.log(`[Foundation Event] ${event}`, data ?? '')\n }\n}\n"],"mappings":"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","names":["unwrapResponse","json","extractError","status","body","errorObj","message","details","detailMessages","d","customMessage","createHttpClient","config","headers","token","request","baseUrl","path","method","options","hdrs","url","searchParams","key","value","qs","fetchOptions","response","rawFetch","createAuthClient","config","createAuth0Client","client","auth0Domain","auth0ClientId","options","user","email","password","response","err","metadata","_code","_newPassword","fetchAuthSession","signInWithRedirect","signOut","getCurrentUser","Amplify","token","signIn","signUp","resetPassword","code","newPassword","confirmResetPassword","createAuthService","listeners","notifyListeners","fn","authUser","callback","idx","parseJwt","token","jwtPart","queryPart","parts","payloadStr","jwtPayload","value","key","apiBaseUrl","websocketBaseUrl","accountBaseUrl","err","message","createFoundation","options","configHeaders","publicConfigResponse","rawPublicConfig","publicConfig","authConfig","authClient","createAuthClient","authService","createAuthService","apiBaseUrl","accountBaseUrl","token","claims","parseJwt","appId","tenantId","version","http","createHttpClient","backendConfig","err","mergedConfig","namespace","config","app","theme","provider","rest","db","createDbService","files","createFilesService","account","createAccountService","integration","createIntegrationService","openapi","createOpenApiService","log","createLogService","entityListeners","event","callback","idx","apiBase","entity","filters","limit","cursor","orderBy","orderDir","params","id","data","updates","fileData","uploadData","formData","key","value","s3Response","fileId","result","accountBase","service","rawCatalog","rawConnections","catalog","connections","bySource","conn","source","item","conns","c","filtered","configurationId","message","context"]}
1
+ {"version":3,"sources":["../src/http.ts","../src/auth.ts","../src/jwt.ts","../src/foundation.ts"],"sourcesContent":["/**\n * HTTP layer for Foundation API calls.\n * Handles request construction, response unwrapping, and error extraction.\n */\n\n/**\n * Unwrap backend response envelope.\n * The API wraps responses in { response: ... } or { data: ... }.\n */\nexport function unwrapResponse(json: Record<string, unknown>): unknown {\n if (json?.response !== undefined) return json.response\n if (json?.data !== undefined) return json.data\n return json\n}\n\n/**\n * Extract a meaningful error from a failed API response.\n */\nexport function extractError(status: number, body: Record<string, unknown>): Error {\n const errorObj = body?.error as Record<string, unknown> | undefined\n\n if (errorObj) {\n let message = errorObj.message as string || 'Unknown error'\n const details = errorObj.details as Array<{ field?: string; message?: string }> | undefined\n if (details?.length) {\n const detailMessages = details\n .map(d => d.field ? `${d.field}: ${d.message}` : d.message)\n .join(', ')\n message = message ? `${message} ${detailMessages}` : detailMessages\n }\n return Object.assign(new Error(message), {\n code: errorObj.code,\n type: errorObj.code,\n details,\n status\n })\n }\n\n const customMessage = (body?.data as Record<string, unknown>)?.message || body?.message\n if (customMessage) {\n return Object.assign(new Error(customMessage as string), { status })\n }\n\n return Object.assign(new Error(`HTTP ${status}`), { status })\n}\n\nexport interface HttpClientConfig {\n appId: string\n tenantId: string\n version: string\n getToken: () => Promise<string>\n}\n\nexport function createHttpClient(config: HttpClientConfig) {\n function headers(token: string): Record<string, string> {\n return {\n 'X-Foundation-Mvp-Application-Id': config.appId,\n 'X-Foundation-Mvp-Tenant-Id': config.tenantId,\n 'X-Foundation-Mvp-Application-Version': config.version,\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n }\n }\n\n async function request(\n baseUrl: string,\n path: string,\n method: string,\n options: { params?: Record<string, unknown>; body?: unknown } = {}\n ): Promise<unknown> {\n const token = await config.getToken()\n const hdrs = headers(token)\n\n let url = `${baseUrl}${path}`\n if (options.params) {\n const searchParams = new URLSearchParams()\n for (const [key, value] of Object.entries(options.params)) {\n if (value !== undefined && value !== null) {\n searchParams.set(key, String(value))\n }\n }\n const qs = searchParams.toString()\n if (qs) url += `?${qs}`\n }\n\n const fetchOptions: RequestInit = { method, headers: hdrs }\n if (options.body !== undefined) {\n fetchOptions.body = JSON.stringify(options.body)\n }\n\n const response = await fetch(url, fetchOptions)\n\n if (!response.ok) {\n let body: Record<string, unknown> = {}\n try { body = await response.json() } catch { /* no json body */ }\n throw extractError(response.status, body)\n }\n\n if (response.status === 204) return null\n\n const json = await response.json()\n return unwrapResponse(json as Record<string, unknown>)\n }\n\n /** Raw fetch with auth headers but no unwrapping (for S3 uploads etc.) */\n async function rawFetch(url: string, options: RequestInit = {}): Promise<Response> {\n return fetch(url, options)\n }\n\n return { request, rawFetch, headers }\n}\n\nexport type HttpClient = ReturnType<typeof createHttpClient>\n","/**\n * Auth provider factory.\n * Creates the right auth client based on config (Cognito/Auth0/none).\n * Supports custom auth client override.\n */\nimport type { AuthClient, AuthService, User } from './types'\n\nconst MAX_LISTENERS = 100\n\nexport interface AuthProviderConfig {\n provider: string\n auth0?: { domain: string; clientId: string; audience?: string; scope?: string }\n cognito?: { userPoolId: string; clientId: string; region: string; domain: string; scope?: string }\n apiUrls?: { apiBaseUrl: string; accountBaseUrl?: string; websocketBaseUrl?: string }\n}\n\nexport async function createAuthClient(config: AuthProviderConfig): Promise<AuthClient> {\n switch (config.provider) {\n case 'auth0': {\n if (!config.auth0) throw new Error('Auth0 config required')\n const { createAuth0Client } = await import('@auth0/auth0-spa-js')\n const client = await createAuth0Client({\n domain: config.auth0.domain,\n clientId: config.auth0.clientId,\n authorizationParams: {\n audience: config.auth0.audience,\n scope: config.auth0.scope || 'openid profile email',\n redirect_uri: window.location.origin\n },\n useRefreshTokens: true,\n cacheLocation: 'localstorage'\n })\n\n const auth0Domain = config.auth0.domain\n const auth0ClientId = config.auth0.clientId\n\n return {\n login: (options) => client.loginWithRedirect(options),\n logout: (options) => client.logout({ logoutParams: { returnTo: window.location.origin }, ...options }),\n getUser: async () => {\n const user = await client.getUser()\n if (!user) return undefined\n return { id: user.sub || '', email: user.email || '', name: user.name, picture: user.picture }\n },\n getTokenSilently: (options) => client.getTokenSilently(options),\n isAuthenticated: () => client.isAuthenticated(),\n\n async signIn(email: string, password: string) {\n // Auth0 Resource Owner Password Grant\n const response = await fetch(`https://${auth0Domain}/oauth/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'password',\n client_id: auth0ClientId,\n username: email,\n password,\n audience: config.auth0!.audience,\n scope: config.auth0!.scope || 'openid profile email'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Sign in failed')\n }\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/signup`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n password,\n connection: 'Username-Password-Authentication',\n ...metadata\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.description || err.message || 'Sign up failed')\n }\n },\n\n async forgotPassword(email: string) {\n const response = await fetch(`https://${auth0Domain}/dbconnections/change_password`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: auth0ClientId,\n email,\n connection: 'Username-Password-Authentication'\n })\n })\n if (!response.ok) {\n const err = await response.json().catch(() => ({}))\n throw new Error(err.error_description || err.message || 'Password reset request failed')\n }\n },\n\n async resetPassword(_code: string, _newPassword: string) {\n // Auth0 handles reset via email link, not code-based flow\n throw new Error('Auth0 password reset is completed via the email link, not a code')\n }\n }\n }\n\n case 'cognito': {\n if (!config.cognito) throw new Error('Cognito config required')\n const { fetchAuthSession, signInWithRedirect, signOut, getCurrentUser } = await import('aws-amplify/auth')\n const { Amplify } = await import('aws-amplify')\n\n Amplify.configure({\n Auth: {\n Cognito: {\n userPoolId: config.cognito.userPoolId,\n userPoolClientId: config.cognito.clientId,\n loginWith: {\n oauth: {\n domain: config.cognito.domain.replace('https://', ''),\n scopes: (config.cognito.scope || 'openid profile email').split(' '),\n redirectSignIn: [window.location.origin],\n redirectSignOut: [window.location.origin],\n responseType: 'code'\n }\n }\n }\n }\n })\n\n return {\n login: async () => { await signInWithRedirect() },\n logout: async () => { await signOut() },\n getUser: async () => {\n try {\n const user = await getCurrentUser()\n return { id: user.userId, email: user.signInDetails?.loginId || '', name: user.username }\n } catch { return undefined }\n },\n getTokenSilently: async () => {\n const session = await fetchAuthSession()\n const token = session.tokens?.accessToken?.toString()\n if (!token) throw new Error('No token available')\n return token\n },\n isAuthenticated: async () => {\n try {\n await getCurrentUser()\n return true\n } catch { return false }\n },\n\n async signIn(email: string, password: string) {\n const { signIn } = await import('aws-amplify/auth')\n await signIn({ username: email, password })\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n const { signUp } = await import('aws-amplify/auth')\n await signUp({\n username: email,\n password,\n options: { userAttributes: { email, ...metadata } }\n })\n },\n\n async forgotPassword(email: string) {\n const { resetPassword } = await import('aws-amplify/auth')\n await resetPassword({ username: email })\n },\n\n async resetPassword(code: string, newPassword: string) {\n const { confirmResetPassword } = await import('aws-amplify/auth')\n // Note: caller must track the username from the forgotPassword call\n await confirmResetPassword({ username: '', confirmationCode: code, newPassword })\n }\n }\n }\n\n case 'none':\n return {\n login: async () => {},\n logout: async () => {},\n getUser: async () => undefined,\n getTokenSilently: async () => 'none',\n isAuthenticated: async () => true\n }\n\n default:\n throw new Error(`Unknown auth provider: ${config.provider}`)\n }\n}\n\n/**\n * Wrap an AuthClient into the reactive AuthService interface.\n */\nexport function createAuthService(client: AuthClient): AuthService {\n let user: User | null = null\n const listeners: Array<(user: User | null) => void> = []\n\n function notifyListeners() {\n listeners.forEach(fn => { try { fn(user) } catch { /* */ } })\n }\n\n return {\n get user() { return user },\n get isAuthenticated() { return !!user },\n\n async getToken() {\n return client.getTokenSilently()\n },\n\n async login(options) {\n await client.login(options)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async logout(options) {\n await client.logout(options)\n user = null\n notifyListeners()\n },\n\n async signIn(email: string, password: string) {\n if (!client.signIn) throw new Error('signIn not supported by this auth provider')\n await client.signIn(email, password)\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n notifyListeners()\n },\n\n async signUp(email: string, password: string, metadata?: Record<string, unknown>) {\n if (!client.signUp) throw new Error('signUp not supported by this auth provider')\n await client.signUp(email, password, metadata)\n },\n\n async forgotPassword(email: string) {\n if (!client.forgotPassword) throw new Error('forgotPassword not supported by this auth provider')\n await client.forgotPassword(email)\n },\n\n async resetPassword(code: string, newPassword: string) {\n if (!client.resetPassword) throw new Error('resetPassword not supported by this auth provider')\n await client.resetPassword(code, newPassword)\n },\n\n onChange(callback) {\n if (listeners.length >= MAX_LISTENERS) {\n console.warn('[Foundation SDK] Auth listener limit reached.')\n return () => {}\n }\n listeners.push(callback)\n return () => {\n const idx = listeners.indexOf(callback)\n if (idx > -1) listeners.splice(idx, 1)\n }\n },\n\n /** @internal Initialize user state from auth client */\n async _initUser() {\n const authenticated = await client.isAuthenticated()\n if (authenticated) {\n const authUser = await client.getUser()\n user = authUser ? { id: authUser.id, email: authUser.email, name: authUser.name, picture: authUser.picture } : null\n }\n }\n } as AuthService & { _initUser(): Promise<void> }\n}\n","export interface JwtClaims {\n sub: string\n apiBaseUrl: string\n accountBaseUrl: string\n websocketBaseUrl: string\n userId: string\n namespace?: string\n}\n\nexport function parseJwt(token: string): JwtClaims {\n if (!token) {\n throw new Error('Token parsing failed: Missing auth token')\n }\n\n try {\n // Auth0 tokens can have query params appended: \"jwt?param=value\"\n const [jwtPart, queryPart] = token.split('?')\n\n const parts = jwtPart.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n const payloadStr = atob(parts[1])\n const jwtPayload = JSON.parse(payloadStr)\n\n // Merge query params if present\n if (queryPart) {\n const params = new URLSearchParams(queryPart)\n params.forEach((value, key) => {\n jwtPayload[key] = value\n })\n }\n\n const apiBaseUrl = jwtPayload['BaseApplication/apiBaseUrl']\n if (!apiBaseUrl) {\n throw new Error('Token missing apiBaseUrl')\n }\n\n const websocketBaseUrl = jwtPayload['BaseApplication/websocketBaseUrl'] || ''\n const accountBaseUrl = jwtPayload['BaseApplication/accountBaseUrl'] || apiBaseUrl\n\n return {\n sub: jwtPayload.sub || '',\n apiBaseUrl,\n accountBaseUrl,\n websocketBaseUrl,\n userId: jwtPayload['BaseApplication/userId'] || '',\n namespace: jwtPayload['BaseApplication/namespace']\n }\n } catch (err) {\n if (err instanceof Error && err.message.startsWith('Token')) {\n throw err\n }\n const message = err instanceof Error ? err.message : 'Failed to parse token'\n throw new Error(`Token parsing failed: ${message}`)\n }\n}\n","/**\n * Foundation SDK — typed API client for the Foundation platform.\n *\n * One input: a config URL. The SDK fetches it, discovers auth, API URLs,\n * features, plans, theme, connectors — everything. Self-configuring.\n */\nimport type {\n Foundation,\n FoundationConfig,\n FullConfig,\n AuthService,\n DbService,\n FilesService,\n AccountService,\n IntegrationService,\n Integration,\n IntegrationConnection,\n IntegrationDetail,\n OpenApiService,\n LogService,\n EntityChangeEvent,\n User\n} from './types'\nimport { createHttpClient, unwrapResponse, type HttpClient } from './http'\nimport { createAuthClient, createAuthService, type AuthProviderConfig } from './auth'\nimport { parseJwt } from './jwt'\n\nexport async function createFoundation(options: FoundationConfig): Promise<Foundation> {\n // 1. Resolve config URL — foundation-env.json wins if it exists (deployed env)\n let configUrl = options.configUrl\n let resolvedAppId = options.appId\n let resolvedTenantId = options.tenantId\n\n try {\n const envResponse = await fetch('/foundation-env.json')\n if (envResponse.ok) {\n const env = await envResponse.json()\n if (env.configUrl) {\n configUrl = env.configUrl\n resolvedAppId = env.applicationId || resolvedAppId\n resolvedTenantId = env.applicationTenant || resolvedTenantId\n }\n }\n } catch { /* no env file — use passed options */ }\n\n if (!configUrl) {\n throw new Error('No configUrl provided and /foundation-env.json not found')\n }\n\n // 2. Fetch public config\n const configHeaders: Record<string, string> = { 'Accept': 'application/json', 'Cache-Control': 'no-cache' }\n if (resolvedAppId) configHeaders['X-Foundation-Mvp-Application-Id'] = resolvedAppId\n if (resolvedTenantId) configHeaders['X-Foundation-Mvp-Tenant-Id'] = resolvedTenantId\n\n const publicConfigResponse = await fetch(configUrl, { headers: configHeaders })\n if (!publicConfigResponse.ok) {\n throw new Error(`Failed to fetch config: ${publicConfigResponse.statusText}`)\n }\n const rawPublicConfig = await publicConfigResponse.json()\n const publicConfig = rawPublicConfig.data ?? rawPublicConfig\n\n // 2. Set up auth\n const authConfig: AuthProviderConfig = publicConfig.auth || { provider: 'none' }\n const authClient = options.auth || await createAuthClient(authConfig)\n const authServiceRaw = createAuthService(authClient)\n const authService = authServiceRaw as AuthService & { _initUser(): Promise<void> }\n await authService._initUser()\n\n // 3. Determine API URLs\n let apiBaseUrl: string\n let accountBaseUrl: string\n\n if (options.baseUrl) {\n // Explicit override (e.g. '/api' with a dev proxy)\n apiBaseUrl = options.baseUrl\n accountBaseUrl = options.baseUrl\n } else if (authConfig.apiUrls?.apiBaseUrl) {\n // API URLs from public config (no-auth mode or explicit)\n apiBaseUrl = authConfig.apiUrls.apiBaseUrl\n accountBaseUrl = authConfig.apiUrls.accountBaseUrl || apiBaseUrl\n } else {\n // API URLs from JWT token\n const token = await authClient.getTokenSilently()\n const claims = parseJwt(token)\n apiBaseUrl = claims.apiBaseUrl\n accountBaseUrl = claims.accountBaseUrl\n }\n\n // 4. Create HTTP client\n const appId = resolvedAppId || publicConfig.app?.id || publicConfig.tenant?.identifier || ''\n const tenantId = resolvedTenantId || publicConfig.tenant?.identifier || ''\n const version = publicConfig.app?.version || publicConfig.core?.version || '0.0.0'\n\n const http = createHttpClient({\n appId,\n tenantId,\n version,\n getToken: () => authClient.getTokenSilently()\n })\n\n // 5. Fetch backend config (authenticated)\n let backendConfig: Record<string, unknown> = {}\n try {\n const cfg = await http.request(apiBaseUrl, '/api/v1/config/init', 'GET')\n backendConfig = (cfg || {}) as Record<string, unknown>\n } catch (err) {\n console.warn('[Foundation SDK] Backend config fetch failed:', err)\n }\n\n // 6. Merge configs\n const mergedConfig = { ...publicConfig, ...backendConfig }\n\n // Determine namespace from JWT if available\n let namespace = ''\n try {\n const token = await authClient.getTokenSilently()\n if (token && token !== 'none') {\n const claims = parseJwt(token)\n namespace = claims.namespace || ''\n }\n } catch { /* no token yet */ }\n\n // 7. Build config service\n const config: FullConfig = {\n get app() {\n const app = mergedConfig.app as Record<string, unknown> || {}\n return {\n id: (app.id || appId) as string,\n name: (app.name || '') as string,\n version: (app.version || version) as string,\n environment: (app.environment || '') as string,\n ...app\n }\n },\n get features() { return (mergedConfig.features || {}) as Record<string, unknown> },\n get plans() { return (mergedConfig.plans || []) as unknown[] },\n get theme() {\n const theme = mergedConfig.theme as Record<string, unknown> || {}\n return {\n colors: (theme.colors || {}) as Record<string, string>,\n dark: (theme.dark || {}) as Record<string, string>,\n defaultColorScheme: theme.defaultColorScheme as string | undefined\n }\n },\n get connectors() { return (mergedConfig.connectors || {}) as Record<string, unknown> },\n get resources() { return (mergedConfig.resources || {}) as Record<string, string> },\n get auth() {\n const { provider, ...rest } = authConfig\n return { provider, ...rest } as { provider: string; [key: string]: unknown }\n },\n get raw() { return mergedConfig }\n }\n\n // 8. Build services\n const db = createDbService(http, apiBaseUrl)\n const files = createFilesService(http, apiBaseUrl, namespace)\n const account = createAccountService(http, accountBaseUrl)\n const integration = createIntegrationService(http, apiBaseUrl, accountBaseUrl, namespace)\n const openapi = createOpenApiService(http, apiBaseUrl)\n const log = createLogService()\n\n // Entity change listeners (WebSocket support is future)\n const entityListeners: Array<(event: EntityChangeEvent) => void> = []\n\n const foundation: Foundation = {\n get ready() { return Promise.resolve() },\n get isReady() { return true },\n auth: authService,\n db,\n files,\n integration,\n account,\n config,\n openapi,\n log,\n on(event, callback) {\n if (event === 'entity.changed') {\n entityListeners.push(callback)\n return () => {\n const idx = entityListeners.indexOf(callback)\n if (idx > -1) entityListeners.splice(idx, 1)\n }\n }\n return () => {}\n }\n }\n\n return foundation\n}\n\n// --- Service factories ---\n\nfunction createDbService(http: HttpClient, apiBase: string): DbService {\n return {\n async list(entity, options = {}) {\n const { filters, limit, cursor, orderBy, orderDir } = options\n const params: Record<string, unknown> = { ...filters }\n if (limit) params.limit = limit\n if (cursor) params.next = cursor\n if (orderBy) params.orderBy = orderBy\n if (orderDir) params.orderDir = orderDir\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params }) as Promise<any>\n },\n async get(entity, id) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'GET', { params: { id } }) as Promise<any>\n },\n async create(entity, data) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n },\n async update(entity, id, updates) {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: { id, ...updates } }) as Promise<any>\n },\n async save(entity, data) {\n try {\n return await http.request(apiBase, `/api/v1/core/${entity}`, 'PUT', { body: data }) as Promise<any>\n } catch {\n return http.request(apiBase, `/api/v1/core/${entity}`, 'POST', { body: data }) as Promise<any>\n }\n },\n async delete(entity, id) {\n await http.request(apiBase, `/api/v1/core/${entity}`, 'DELETE', { body: { id } })\n }\n }\n}\n\nfunction createFilesService(http: HttpClient, apiBase: string, namespace: string): FilesService {\n return {\n async initiate(options) {\n return http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { ...options, __namespace: namespace }\n }) as Promise<any>\n },\n async upload(options) {\n let fileData: ArrayBuffer\n if (options.file instanceof ArrayBuffer) {\n fileData = options.file\n } else {\n fileData = await options.file.arrayBuffer()\n }\n\n const uploadData = await http.request(apiBase, '/api/v1/core/upload', 'POST', {\n body: { name: options.name, contentType: options.contentType, contentLength: fileData.byteLength, sha256: options.sha256, __namespace: namespace }\n }) as { id: string; name: string; signedUrl: string; signedData: Record<string, string> }\n\n if (!uploadData.signedUrl || !uploadData.signedData) {\n throw new Error('Missing signedUrl or signedData in response')\n }\n\n const formData = new FormData()\n Object.entries(uploadData.signedData).forEach(([key, value]) => {\n formData.append(key, value)\n })\n formData.append('file', new Blob([fileData], { type: options.contentType }), options.name)\n\n const s3Response = await fetch(uploadData.signedUrl, { method: 'POST', body: formData })\n if (s3Response.status !== 204) {\n throw new Error(`S3 upload failed: ${s3Response.status}`)\n }\n\n return { id: uploadData.id, name: uploadData.name, status: 'uploaded', s3UploadComplete: true }\n },\n async get(fileId) {\n return http.request(apiBase, '/api/v1/core/files', 'GET', {\n params: { id: fileId, __namespace: namespace }\n }) as Promise<any>\n },\n async delete(fileId) {\n await http.request(apiBase, `/api/v1/core/files/${fileId}`, 'DELETE')\n },\n async list(options = {}) {\n const params: Record<string, unknown> = { __namespace: namespace }\n if (options.limit) params.limit = options.limit\n if (options.cursor) params.cursor = options.cursor\n const result = await http.request(apiBase, '/api/v1/core/files', 'GET', { params }) as {\n items?: unknown[]; next?: string\n }\n return { items: result?.items || [], nextCursor: result?.next } as any\n }\n }\n}\n\nfunction createAccountService(http: HttpClient, accountBase: string): AccountService {\n return {\n async get() {\n return http.request(accountBase, '/api/v1/accounts/account', 'GET') as Promise<any>\n },\n async update(data) {\n await http.request(accountBase, '/api/v1/accounts/account', 'PUT', { body: { user: data } })\n },\n async usage() {\n return http.request(accountBase, '/api/v1/accounts/account/usage', 'GET') as Promise<any>\n },\n async resendVerification() {\n await http.request(accountBase, '/api/v1/accounts/account/resend-verification', 'POST')\n }\n }\n}\n\nfunction createIntegrationService(http: HttpClient, apiBase: string, accountBase: string, namespace: string): IntegrationService {\n const service: IntegrationService = {\n async list() {\n return http.request(apiBase, '/api/v1/config/connectors', 'GET') as Promise<any>\n },\n async connections() {\n return http.request(apiBase, '/api/v1/core/integrations', 'GET', {\n params: { query: 'default', __namespace: namespace }\n }) as Promise<any>\n },\n async all() {\n const [rawCatalog, rawConnections] = await Promise.all([\n service.list(),\n service.connections()\n ])\n\n const catalog = (Array.isArray(rawCatalog) ? rawCatalog : (rawCatalog as any)?.items || []) as Integration[]\n const connections = (Array.isArray(rawConnections) ? rawConnections : (rawConnections as any)?.items || []) as IntegrationConnection[]\n\n const bySource = new Map<string, IntegrationConnection[]>()\n for (const conn of connections) {\n const source = conn.source || conn.id\n if (!bySource.has(source)) bySource.set(source, [])\n bySource.get(source)!.push(conn)\n }\n\n return catalog.map(item => {\n const conns = bySource.get(item.id) || []\n return {\n ...item,\n connections: conns,\n connected: conns.some(c => c.connected),\n connectionCount: conns.filter(c => c.connected).length\n } as IntegrationDetail\n })\n },\n async status(source) {\n const conns = await service.connections()\n const items = (Array.isArray(conns) ? conns : (conns as any)?.items || []) as IntegrationConnection[]\n const filtered = items.filter(c => c.source === source && c.connected)\n return { connected: filtered.length > 0, connections: filtered }\n },\n async connect(source) {\n return http.request(accountBase, `/api/v1/accounts/integrations/${source}/initialize`, 'POST', {\n body: { __namespace: namespace }\n }) as Promise<any>\n },\n async disconnect(source, configurationId) {\n await http.request(accountBase, `/api/v1/accounts/integrations/${source}/remove`, 'POST', {\n body: { configurationId }\n })\n }\n }\n return service\n}\n\nfunction createOpenApiService(http: HttpClient, apiBase: string): OpenApiService {\n return {\n async get() {\n return http.request(apiBase, '/api/v1/config/openapi', 'GET') as Promise<any>\n }\n }\n}\n\nfunction createLogService(): LogService {\n return {\n info: (message, context) => console.log(`[Foundation] ${message}`, context ?? ''),\n warn: (message, context) => console.warn(`[Foundation] ${message}`, context ?? ''),\n error: (message, context) => console.error(`[Foundation] ${message}`, context ?? ''),\n event: (event, data) => console.log(`[Foundation Event] ${event}`, data ?? '')\n }\n}\n"],"mappings":"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","names":["unwrapResponse","json","extractError","status","body","errorObj","message","details","detailMessages","d","customMessage","createHttpClient","config","headers","token","request","baseUrl","path","method","options","hdrs","url","searchParams","key","value","qs","fetchOptions","response","rawFetch","createAuthClient","config","createAuth0Client","client","auth0Domain","auth0ClientId","options","user","email","password","response","err","metadata","_code","_newPassword","fetchAuthSession","signInWithRedirect","signOut","getCurrentUser","Amplify","token","signIn","signUp","resetPassword","code","newPassword","confirmResetPassword","createAuthService","listeners","notifyListeners","fn","authUser","callback","idx","parseJwt","token","jwtPart","queryPart","parts","payloadStr","jwtPayload","value","key","apiBaseUrl","websocketBaseUrl","accountBaseUrl","err","message","createFoundation","options","configUrl","resolvedAppId","resolvedTenantId","envResponse","env","configHeaders","publicConfigResponse","rawPublicConfig","publicConfig","authConfig","authClient","createAuthClient","authService","createAuthService","apiBaseUrl","accountBaseUrl","token","claims","parseJwt","appId","tenantId","version","http","createHttpClient","backendConfig","err","mergedConfig","namespace","config","app","theme","provider","rest","db","createDbService","files","createFilesService","account","createAccountService","integration","createIntegrationService","openapi","createOpenApiService","log","createLogService","entityListeners","event","callback","idx","apiBase","entity","filters","limit","cursor","orderBy","orderDir","params","id","data","updates","fileData","uploadData","formData","key","value","s3Response","fileId","result","accountBase","service","rawCatalog","rawConnections","catalog","connections","bySource","conn","source","item","conns","c","filtered","configurationId","message","context"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foundation-sdk",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "TypeScript SDK for Foundation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",