@donotdev/supabase 0.0.2 → 0.0.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- import{isClient as b,redirectToExternalUrl as E,hasProvider as P,getProvider as k,createDefaultUserProfile as I,SUBSCRIPTION_TIERS as U,hasRoleAccess as _,wrapAuthError as i,DoNotDevError as n}from"@donotdev/core";import{AuthHardening as W}from"@donotdev/core";function o(c){const t=c.user_metadata??{},e=c.app_metadata??{};return{id:c.id,email:c.email??void 0,displayName:t.full_name??t.name??void 0,photoURL:t.avatar_url??void 0,emailVerified:!!c.email_confirmed_at,role:e.role??"guest",customClaims:{...t,...e}}}const m={google:"google",github:"github",facebook:"facebook",apple:"apple",discord:"discord",slack:"slack",microsoft:"microsoft",spotify:"spotify",twitch:"twitch",twitter:"twitter",x:"twitter",linkedin:"linkedin",notion:"notion",medium:"medium",reddit:"reddit",yahoo:"yahoo",youtube:"youtube"};class v{client;store=null;initialized=!1;security=null;defaultHardening=new W;constructor(t){this.client=t}setStore(t){this.store=t}setSecurity(t){this.security=t}get _hardening(){return this.security?.authHardening??this.defaultHardening}_checkLockout(t){try{this._hardening.checkLockout(t)}catch(e){throw i(e instanceof Error?e:new Error(String(e)),"SupabaseAuth","signInWithEmailAndPassword",{email:t})}}_recordFailure(t){this._hardening.recordFailure(t);try{this._hardening.checkLockout(t)}catch{this.security?.audit({type:"auth.locked"})}this.security?.audit({type:"auth.login.failure"})}_recordSuccess(t){this._hardening.recordSuccess(t)}async initialize(){if(!this.initialized)try{const{data:t}=await this.client.auth.getSession();t.session?.user?await this.handleAuthStateChange(t.session.user):this.store?.setUnauthenticated(),this.initialized=!0}catch{this.store?.setUnauthenticated()}}async getCurrentUser(){const{data:{user:t}}=await this.client.auth.getUser();return t?o(t):null}async handleAuthStateChange(t){if(!this.store)return;const e=o(t),a={userId:e.id,tier:e.customClaims?.tier||U.FREE,status:"active",isActive:!0,features:[],subscriptionId:null,customerId:e.id,subscriptionEnd:null,cancelAtPeriodEnd:!1,updatedAt:new Date().toISOString()},s={...I(e.id),email:e.email??void 0,displayName:e.displayName??void 0,photoURL:e.photoURL??void 0,role:e.role};this.store.setAuthenticated(e,a,s)}async signInWithEmailAndPassword(t,e){this._checkLockout(t);try{const{data:{user:a},error:s}=await this.client.auth.signInWithPassword({email:t,password:e});if(s)throw this._recordFailure(t),i(s,"SupabaseAuth","signInWithEmailAndPassword",{email:t});if(!a)throw this._recordFailure(t),i(new Error("Sign in failed"),"SupabaseAuth","signInWithEmailAndPassword",{email:t});return this._recordSuccess(t),this.security?.audit({type:"auth.login.success",userId:a.id}),o(a)}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","signInWithEmailAndPassword",{email:t})}}async createUserWithEmailAndPassword(t,e){try{const{data:{user:a},error:s}=await this.client.auth.signUp({email:t,password:e});if(s)throw i(s,"SupabaseAuth","createUserWithEmailAndPassword",{email:t});if(!a)throw i(new Error("Sign up failed"),"SupabaseAuth","createUserWithEmailAndPassword",{email:t});if(Array.isArray(a.identities)&&a.identities.length===0)throw i(new Error("An account with this email already exists"),"SupabaseAuth","createUserWithEmailAndPassword",{email:t});return o(a)}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","createUserWithEmailAndPassword",{email:t})}}async signOut(){let t;try{const{data:{user:e}}=await this.client.auth.getUser();t=e?.id}catch{}await this.client.auth.signOut(),this.store?.setUnauthenticated(),this.security?.audit({type:"auth.logout",userId:t})}async sendPasswordResetEmail(t){this.security&&await this.security.checkRateLimit(`password_reset:${t}`,"write");try{const{error:e}=await this.client.auth.resetPasswordForEmail(t);if(e)throw i(e,"SupabaseAuth","sendPasswordResetEmail",{email:t});this.security?.audit({type:"auth.password.reset"})}catch(e){throw e instanceof n?e:i(e,"SupabaseAuth","sendPasswordResetEmail",{email:t})}}async updateUserProfile(t){try{const{data:{user:e}}=await this.client.auth.getUser();if(!e)throw i(new Error("No current user"),"SupabaseAuth","updateUserProfile");const a=e.user_metadata??{},s={full_name:t.displayName??a.full_name,name:t.displayName??a.name,avatar_url:t.photoURL??a.avatar_url},{error:r}=await this.client.auth.updateUser({data:s});if(r)throw i(r,"SupabaseAuth","updateUserProfile")}catch(e){throw e instanceof n?e:i(e,"SupabaseAuth","updateUserProfile")}}async getAccessToken(){const{data:{session:t}}=await this.client.auth.getSession();return t?.access_token??null}async refreshToken(){const{data:{session:t},error:e}=await this.client.auth.refreshSession();return e?null:t?.access_token??null}onAuthStateChanged(t){const{data:{subscription:e}}=this.client.auth.onAuthStateChange((a,s)=>{const r=s?.user||null;r?this.handleAuthStateChange(r).then(()=>{t(o(r))}).catch(()=>{t(o(r))}):(this.store?.setUnauthenticated(),t(null))});return()=>e.unsubscribe()}async hasRole(t){const e=await this.getCurrentUser();if(!e)return!1;const a=e.role??"guest";return _(a,t)}async hasFeature(t){const e=await this.getCurrentUser();if(!e?.customClaims)return!1;const a=e.customClaims.features;return Array.isArray(a)&&a.includes(t)}async hasTier(t){const e=await this.getCurrentUser();return e?.customClaims?e.customClaims.tier===t:!1}async signInWithEmail(t,e){return{user:await this.signInWithEmailAndPassword(t,e),success:!0}}async createUserWithEmail(t,e){return{user:await this.createUserWithEmailAndPassword(t,e),success:!0,isNewUser:!0}}async signInWithPartner(t,e){try{const a=m[t]??t;if(b()){const{data:u,error:l}=await this.client.auth.signInWithOAuth({provider:a,options:{skipBrowserRedirect:!0,redirectTo:window.location.origin}});if(l)throw i(l,"SupabaseAuth","signInWithPartner",{partnerId:t});if(u?.url){const d=window.screen.width/2-300,w=window.screen.height/2-700/2,h=window.open(u.url,"supabase-auth-popup",`width=600,height=700,left=${d},top=${w},resizable=yes,scrollbars=yes,status=yes`);if(!h)throw new Error("Popup blocked. Please allow popups for this site.");return new Promise(g=>{let y=null;const f=setInterval(async()=>{if(h.closed){clearInterval(f),y?.unsubscribe();const p=await this.getCurrentUser();g(p?{user:p,success:!0}:null)}},500),{data:{subscription:A}}=this.client.auth.onAuthStateChange((p,S)=>{p==="SIGNED_IN"&&S?.user&&(clearInterval(f),A.unsubscribe(),h.close(),g({user:o(S.user),success:!0}))});y=A})}}const{data:s,error:r}=await this.client.auth.signInWithOAuth({provider:a});if(r)throw i(r,"SupabaseAuth","signInWithPartner",{partnerId:t});return s?.url&&await E(s.url,{validateUrl:!0}),null}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","signInWithPartner",{partnerId:t})}}async linkWithPartner(t,e){try{const a=m[t]??t,{data:s,error:r}=await this.client.auth.linkIdentity({provider:a});if(r)throw i(r,"SupabaseAuth","linkWithPartner",{partnerId:t});const u=s?.user??(await this.client.auth.getUser()).data?.user;return u?{user:o(u),success:!0}:null}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","linkWithPartner",{partnerId:t})}}async signInWithGoogleCredential(t){return null}async updatePassword(t){try{const{error:e}=await this.client.auth.updateUser({password:t});if(e)throw i(e,"SupabaseAuth","updatePassword")}catch(e){throw e instanceof n?e:i(e,"SupabaseAuth","updatePassword")}}async sendEmailVerification(){try{const{data:{user:t}}=await this.client.auth.getUser();if(!t?.email)return;const{error:e}=await this.client.auth.resend({type:"signup",email:t.email});if(e)throw i(e,"SupabaseAuth","sendEmailVerification")}catch(t){throw t instanceof n?t:i(t,"SupabaseAuth","sendEmailVerification")}}async sendSignInLinkToEmail(t,e){try{const a=e?.url??(typeof window<"u"?window.location.origin:void 0),{error:s}=await this.client.auth.signInWithOtp({email:t,options:a?{emailRedirectTo:a}:void 0});if(s)throw i(s,"SupabaseAuth","sendSignInLinkToEmail",{email:t})}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","sendSignInLinkToEmail",{email:t})}}async signInWithEmailLink(t,e){if(!e)return null;try{const a=new URL(e),s=a.searchParams.get("token")||a.searchParams.get("token_hash")||"",r=a.searchParams.get("type")||"magiclink";if(!s){const d=a.hash?.slice(1)||"";if(!d)return null;const{data:{user:w},error:h}=await this.client.auth.verifyOtp({token_hash:d,type:"magiclink"});return h?null:w?{user:o(w),success:!0}:null}const{data:{user:u},error:l}=await this.client.auth.verifyOtp({token_hash:s,type:r});return l?null:u?{user:o(u),success:!0}:null}catch{return null}}isSignInWithEmailLink(t){if(!t)return!1;try{const e=new URL(t);return e.searchParams.has("token")||e.searchParams.has("token_hash")||e.searchParams.get("type")==="magiclink"||e.hash.includes("token_hash=")||e.hash.includes("type=magiclink")}catch{return t.includes("token=")||t.includes("token_hash=")||t.includes("type=magiclink")}}async getEmailVerificationStatus(){const{data:{user:t}}=await this.client.auth.getUser();return{status:t?.email_confirmed_at?"verified":"pending"}}async isEmailVerificationEnabled(){return!0}async reauthenticateWithPassword(t){try{const{data:{user:e}}=await this.client.auth.getUser();if(!e?.email)throw i(new Error("No email"),"SupabaseAuth","reauthenticateWithPassword");this._checkLockout(e.email);const{error:a}=await this.client.auth.signInWithPassword({email:e.email,password:t});if(a)throw this._recordFailure(e.email),i(a,"SupabaseAuth","reauthenticateWithPassword");this._recordSuccess(e.email)}catch(e){throw e instanceof n?e:i(e,"SupabaseAuth","reauthenticateWithPassword")}}async reauthenticateWithProvider(t,e){try{const a=m[t]??t,{data:s,error:r}=await this.client.auth.signInWithOAuth({provider:a});if(r)throw i(r,"SupabaseAuth","reauthenticateWithProvider",{partnerId:t});s?.url&&b()&&await E(s.url,{validateUrl:!0})}catch(a){throw a instanceof n?a:i(a,"SupabaseAuth","reauthenticateWithProvider",{partnerId:t})}}async deleteAccount(t){try{if(P("callable")){await k("callable").call("delete-account",{}),await this.client.auth.signOut();return}const e=new Error("Account deletion requires a server endpoint. Configure a callable provider or deploy a delete-account Edge Function.");throw e.code="DELETE_ACCOUNT_REQUIRES_SERVER",i(e,"SupabaseAuth","deleteAccount")}catch(e){throw e instanceof n?e:i(e,"SupabaseAuth","deleteAccount")}}}export{v as SupabaseAuth};
1
+ import{isClient as E,redirectToExternalUrl as P,hasProvider as U,getProvider as k,createDefaultUserProfile as W,SUBSCRIPTION_TIERS as I,hasRoleAccess as v,wrapAuthError as s,DoNotDevError as n}from"@donotdev/core";import{AuthHardening as R}from"@donotdev/core";function o(c){const t=c.user_metadata??{},e=c.app_metadata??{};return{id:c.id,email:c.email??void 0,displayName:t.full_name??t.name??void 0,photoURL:t.avatar_url??void 0,emailVerified:!!c.email_confirmed_at,role:e.role??"guest",customClaims:{...t,...e}}}const y={google:"google",github:"github",facebook:"facebook",apple:"apple",discord:"discord",slack:"slack",microsoft:"microsoft",spotify:"spotify",twitch:"twitch",twitter:"twitter",x:"twitter",linkedin:"linkedin",notion:"notion",medium:"medium",reddit:"reddit",yahoo:"yahoo",youtube:"youtube"};class N{client;store=null;initialized=!1;security=null;defaultHardening=new R;constructor(t){this.client=t}setStore(t){this.store=t}setSecurity(t){this.security=t}get _hardening(){return this.security?.authHardening??this.defaultHardening}_checkLockout(t){try{this._hardening.checkLockout(t)}catch(e){throw s(e instanceof Error?e:new Error(String(e)),"SupabaseAuth","signInWithEmailAndPassword",{email:t})}}_recordFailure(t){this._hardening.recordFailure(t);try{this._hardening.checkLockout(t)}catch{this.security?.audit({type:"auth.locked"})}this.security?.audit({type:"auth.login.failure"})}_recordSuccess(t){this._hardening.recordSuccess(t)}async initialize(){if(!this.initialized)try{const{data:t}=await this.client.auth.getSession();t.session?.user?await this.handleAuthStateChange(t.session.user):this.store?.setUnauthenticated(),this.initialized=!0}catch{this.store?.setUnauthenticated()}}async getCurrentUser(){const{data:{user:t}}=await this.client.auth.getUser();return t?o(t):null}async handleAuthStateChange(t){if(!this.store)return;const e=o(t),r={userId:e.id,tier:e.customClaims?.tier||I.FREE,status:"active",isActive:!0,features:[],subscriptionId:null,customerId:e.id,subscriptionEnd:null,cancelAtPeriodEnd:!1,updatedAt:new Date().toISOString()},a={...W(e.id),email:e.email??void 0,displayName:e.displayName??void 0,photoURL:e.photoURL??void 0,role:e.role};this.store.setAuthenticated(e,r,a)}async signInWithEmailAndPassword(t,e){this._checkLockout(t);try{const{data:{user:r},error:a}=await this.client.auth.signInWithPassword({email:t,password:e});if(a)throw this._recordFailure(t),s(a,"SupabaseAuth","signInWithEmailAndPassword",{email:t});if(!r)throw this._recordFailure(t),s(new Error("Sign in failed"),"SupabaseAuth","signInWithEmailAndPassword",{email:t});return this._recordSuccess(t),this.security?.audit({type:"auth.login.success",userId:r.id}),o(r)}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","signInWithEmailAndPassword",{email:t})}}async createUserWithEmailAndPassword(t,e){try{const{data:{user:r},error:a}=await this.client.auth.signUp({email:t,password:e});if(a)throw s(a,"SupabaseAuth","createUserWithEmailAndPassword",{email:t});if(!r)throw s(new Error("Sign up failed"),"SupabaseAuth","createUserWithEmailAndPassword",{email:t});if(Array.isArray(r.identities)&&r.identities.length===0)throw s(new Error("An account with this email already exists"),"SupabaseAuth","createUserWithEmailAndPassword",{email:t});return o(r)}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","createUserWithEmailAndPassword",{email:t})}}async signOut(){let t;try{const{data:{user:e}}=await this.client.auth.getUser();t=e?.id}catch{}await this.client.auth.signOut(),this.store?.setUnauthenticated(),this.security?.audit({type:"auth.logout",userId:t})}async sendPasswordResetEmail(t){this.security&&await this.security.checkRateLimit(`password_reset:${t}`,"write");try{const{error:e}=await this.client.auth.resetPasswordForEmail(t);if(e)throw s(e,"SupabaseAuth","sendPasswordResetEmail",{email:t});this.security?.audit({type:"auth.password.reset"})}catch(e){throw e instanceof n?e:s(e,"SupabaseAuth","sendPasswordResetEmail",{email:t})}}async updateUserProfile(t){try{const{data:{user:e}}=await this.client.auth.getUser();if(!e)throw s(new Error("No current user"),"SupabaseAuth","updateUserProfile");const r=e.user_metadata??{},a={full_name:t.displayName??r.full_name,name:t.displayName??r.name,avatar_url:t.photoURL??r.avatar_url},{error:i}=await this.client.auth.updateUser({data:a});if(i)throw s(i,"SupabaseAuth","updateUserProfile")}catch(e){throw e instanceof n?e:s(e,"SupabaseAuth","updateUserProfile")}}async getAccessToken(){const{data:{session:t}}=await this.client.auth.getSession();return t?.access_token??null}async refreshToken(){const{data:{session:t},error:e}=await this.client.auth.refreshSession();return e?null:t?.access_token??null}onAuthStateChanged(t){const{data:{subscription:e}}=this.client.auth.onAuthStateChange((r,a)=>{const i=a?.user||null;i?this.handleAuthStateChange(i).then(()=>{t(o(i))}).catch(()=>{t(o(i))}):(this.store?.setUnauthenticated(),t(null))});return()=>e.unsubscribe()}async hasRole(t){const e=await this.getCurrentUser();if(!e)return!1;const r=e.role??"guest";return v(r,t)}async hasFeature(t){const e=await this.getCurrentUser();if(!e?.customClaims)return!1;const r=e.customClaims.features;return Array.isArray(r)&&r.includes(t)}async hasTier(t){const e=await this.getCurrentUser();return e?.customClaims?e.customClaims.tier===t:!1}async signInWithEmail(t,e){return{user:await this.signInWithEmailAndPassword(t,e),success:!0}}async createUserWithEmail(t,e){return{user:await this.createUserWithEmailAndPassword(t,e),success:!0,isNewUser:!0}}async signInWithPartner(t,e){try{const r=y[t]??t;if(E()){const{data:u,error:h}=await this.client.auth.signInWithOAuth({provider:r,options:{skipBrowserRedirect:!0,redirectTo:window.location.origin}});if(h)throw s(h,"SupabaseAuth","signInWithPartner",{partnerId:t});if(u?.url){const f=window.screen.width/2-300,_=window.screen.height/2-700/2,p=window.open(u.url,"supabase-auth-popup",`width=600,height=700,left=${f},top=${_},resizable=yes,scrollbars=yes,status=yes`);if(!p)throw new Error("Popup blocked. Please allow popups for this site.");return new Promise(g=>{let m=null;const A=setInterval(async()=>{if(p.closed){clearInterval(A),m?.unsubscribe();const l=await this.getCurrentUser();g(l?{user:l,success:!0}:null)}},500),{data:{subscription:S}}=this.client.auth.onAuthStateChange((l,b)=>{l==="SIGNED_IN"&&b?.user&&(clearInterval(A),S.unsubscribe(),p.close(),g({user:o(b.user),success:!0}))});m=S})}}const{data:a,error:i}=await this.client.auth.signInWithOAuth({provider:r});if(i)throw s(i,"SupabaseAuth","signInWithPartner",{partnerId:t});return a?.url&&await P(a.url,{validateUrl:!0}),null}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","signInWithPartner",{partnerId:t})}}async linkWithPartner(t,e){try{const r=y[t]??t,{data:a,error:i}=await this.client.auth.linkIdentity({provider:r});if(i)throw s(i,"SupabaseAuth","linkWithPartner",{partnerId:t});const u=a?.user??(await this.client.auth.getUser()).data?.user;return u?{user:o(u),success:!0}:null}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","linkWithPartner",{partnerId:t})}}async signInWithGoogleCredential(t){return null}async updatePassword(t){try{const{error:e}=await this.client.auth.updateUser({password:t});if(e)throw s(e,"SupabaseAuth","updatePassword")}catch(e){throw e instanceof n?e:s(e,"SupabaseAuth","updatePassword")}}async sendEmailVerification(){try{const{data:{user:t}}=await this.client.auth.getUser();if(!t?.email)return;const{error:e}=await this.client.auth.resend({type:"signup",email:t.email});if(e)throw s(e,"SupabaseAuth","sendEmailVerification")}catch(t){throw t instanceof n?t:s(t,"SupabaseAuth","sendEmailVerification")}}async sendSignInLinkToEmail(t,e){try{const r=e?.url??(typeof window<"u"?window.location.origin:void 0),{error:a}=await this.client.auth.signInWithOtp({email:t,options:r?{emailRedirectTo:r}:void 0});if(a)throw s(a,"SupabaseAuth","sendSignInLinkToEmail",{email:t})}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","sendSignInLinkToEmail",{email:t})}}async signInWithEmailLink(t,e){if(!e)return null;try{const r=new URL(e),a=r.searchParams.get("token")||r.searchParams.get("token_hash")||"",i=r.searchParams.get("type")||"magiclink";if(!a){const d=r.hash?.slice(1)||"";if(!d)return null;const{data:{user:w},error:f}=await this.client.auth.verifyOtp({token_hash:d,type:"magiclink"});return f?null:w?{user:o(w),success:!0}:null}const{data:{user:u},error:h}=await this.client.auth.verifyOtp({token_hash:a,type:i});return h?null:u?{user:o(u),success:!0}:null}catch{return null}}isSignInWithEmailLink(t){if(!t)return!1;try{const e=new URL(t);return e.searchParams.has("token")||e.searchParams.has("token_hash")||e.searchParams.get("type")==="magiclink"||e.hash.includes("token_hash=")||e.hash.includes("type=magiclink")}catch{return t.includes("token=")||t.includes("token_hash=")||t.includes("type=magiclink")}}async getEmailVerificationStatus(){const{data:{user:t}}=await this.client.auth.getUser();return{status:t?.email_confirmed_at?"verified":"pending"}}async isEmailVerificationEnabled(){return!0}async reauthenticateWithPassword(t){try{const{data:{user:e}}=await this.client.auth.getUser();if(!e?.email)throw s(new Error("No email"),"SupabaseAuth","reauthenticateWithPassword");this._checkLockout(e.email);const{error:r}=await this.client.auth.signInWithPassword({email:e.email,password:t});if(r)throw this._recordFailure(e.email),s(r,"SupabaseAuth","reauthenticateWithPassword");this._recordSuccess(e.email)}catch(e){throw e instanceof n?e:s(e,"SupabaseAuth","reauthenticateWithPassword")}}async reauthenticateWithProvider(t,e){try{const r=y[t]??t,{data:a,error:i}=await this.client.auth.signInWithOAuth({provider:r});if(i)throw s(i,"SupabaseAuth","reauthenticateWithProvider",{partnerId:t});a?.url&&E()&&await P(a.url,{validateUrl:!0})}catch(r){throw r instanceof n?r:s(r,"SupabaseAuth","reauthenticateWithProvider",{partnerId:t})}}async deleteAccount(t){try{if(U("callable")){await k("callable").call("delete-account",{}),await this.client.auth.signOut();return}const e=new Error("Account deletion requires a server endpoint. Configure a callable provider or deploy a delete-account Edge Function.");throw e.code="DELETE_ACCOUNT_REQUIRES_SERVER",s(e,"SupabaseAuth","deleteAccount")}catch(e){throw e instanceof n?e:s(e,"SupabaseAuth","deleteAccount")}}}export{N as SupabaseAuth};
@@ -1 +1 @@
1
- {"version":3,"file":"callableProvider.d.ts","sourceRoot":"","sources":["../../src/client/callableProvider.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAO9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAqD;gBAGvE,MAAM,EAAE,cAAc,EACvC,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B;;;;;WAKG;QACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5B;IAQG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAwCxE"}
1
+ {"version":3,"file":"callableProvider.d.ts","sourceRoot":"","sources":["../../src/client/callableProvider.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,wBAAyB,YAAW,iBAAiB;IAQ9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAErD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CACe;gBAGjC,MAAM,EAAE,cAAc,EACvC,OAAO,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B;;;;;WAKG;QACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5B;IAQG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CA4CxE"}
@@ -1 +1 @@
1
- import{wrapCrudError as e,DoNotDevError as u}from"@donotdev/core";class n{client;crudFunctionName;crudCollections;static CRUD_OP_REGEX=/^(get|create|update|delete|list|listCard)_(.+)$/;constructor(t,o){this.client=t,this.crudFunctionName=o?.crudFunctionName??"crud",this.crudCollections=o?.crudCollections?new Set(o.crudCollections):null}async call(t,o){try{const r=n.CRUD_OP_REGEX.exec(t),a=r!==null&&(this.crudCollections===null||this.crudCollections.has(r[2])),l=a?this.crudFunctionName:t,i=a?{_functionName:t,...o}:o,{data:s,error:c}=await this.client.functions.invoke(l,{body:i});if(c)throw e(c instanceof Error?c:new Error(String(c)),"SupabaseCallableProvider","call",t);return s}catch(r){throw r instanceof u?r:e(r instanceof Error?r:new Error(String(r)),"SupabaseCallableProvider","call",t)}}}export{n as SupabaseCallableProvider};
1
+ import{wrapCrudError as l,DoNotDevError as u}from"@donotdev/core";class n{client;crudFunctionName;crudCollections;static CRUD_OP_REGEX=/^(get|create|update|delete|list|listCard)_(.+)$/;constructor(t,c){this.client=t,this.crudFunctionName=c?.crudFunctionName??"crud",this.crudCollections=c?.crudCollections?new Set(c.crudCollections):null}async call(t,c){try{const r=n.CRUD_OP_REGEX.exec(t),e=r!==null&&(this.crudCollections===null||this.crudCollections.has(r[2])),i=e?this.crudFunctionName:t,s=e?{_functionName:t,...c}:c,{data:a,error:o}=await this.client.functions.invoke(i,{body:s});if(o)throw l(o instanceof Error?o:new Error(String(o)),"SupabaseCallableProvider","call",t);return a}catch(r){throw r instanceof u?r:l(r instanceof Error?r:new Error(String(r)),"SupabaseCallableProvider","call",t)}}}export{n as SupabaseCallableProvider};
@@ -12,8 +12,9 @@
12
12
  * The adapter's field mapper converts app ↔ backend names at the boundary only.
13
13
  *
14
14
  * **Field mapping (single boundary):**
15
- * App field names (camelCase) are always converted to/from backend column names (snake_case).
16
- * No normalization outside this adapter.
15
+ * Write paths convert app field names to backend column names (snake_case) via blind camelToSnake.
16
+ * Read paths use an entity-aware mapper that preserves entity field names as defined in the schema
17
+ * (which may be snake_case or camelCase) so `filterVisibleFields` can match them.
17
18
  *
18
19
  * **Cursor pagination:**
19
20
  * `QueryOptions.startAfter` must be the value of the first `orderBy` field from the last row
@@ -67,7 +68,11 @@ export declare class SupabaseCrudAdapter implements ICrudAdapter {
67
68
  * to prevent memory leaks in long-running server processes.
68
69
  */
69
70
  dispose(): void;
70
- private normalize;
71
+ /**
72
+ * Build an entity-aware mapper when schema is available.
73
+ * Returns entity field names from `fromBackendRow` so `filterVisibleFields` can match them.
74
+ */
75
+ private createEntityMapper;
71
76
  /**
72
77
  * Resolve the current user's role from the Supabase JWT app_metadata.
73
78
  * Result is cached for 30 seconds to avoid a getSession() call on every read/query.
@@ -1 +1 @@
1
- {"version":3,"file":"crudAdapter.d.ts","sourceRoot":"","sources":["../../src/client/crudAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EAEZ,oBAAoB,EACpB,4BAA4B,EAC5B,8BAA8B,EAE9B,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAWxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA4H5D,qBAAa,mBAAoB,YAAW,YAAY;IAwBpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAxB3B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,eAAe,QAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAa;gBAGhC,MAAM,EAAE,cAAc,EACtB,QAAQ,GAAE,MAA0B;IAYvD;;;;OAIG;IACH,mBAAmB,IAAI,IAAI;IAI3B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf,OAAO,CAAC,SAAS;IAIjB;;;;OAIG;YACW,WAAW;IAsBzB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAmBpB,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IA6Bd,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,EACP,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAgDnD,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC;IAuCV,MAAM,CAAC,CAAC,EACZ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IAqCV,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCrD,KAAK,CAAC,CAAC,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,GAChC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IA2GnC,SAAS,CAAC,CAAC,CAAC,EACV,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,4BAA4B,CAAC,CAAC,CAAC,EACzC,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,MAAM,IAAI;IA6Db,qBAAqB,CAAC,CAAC,CAAC,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,EAC3C,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,MAAM,IAAI;CA+Fd"}
1
+ {"version":3,"file":"crudAdapter.d.ts","sourceRoot":"","sources":["../../src/client/crudAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EAEZ,oBAAoB,EACpB,4BAA4B,EAC5B,8BAA8B,EAE9B,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAWxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AA0I5D,qBAAa,mBAAoB,YAAW,YAAY;IAwBpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAxB3B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,eAAe,QAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAa;gBAGhC,MAAM,EAAE,cAAc,EACtB,QAAQ,GAAE,MAA0B;IAcvD;;;;OAIG;IACH,mBAAmB,IAAI,IAAI;IAI3B;;;OAGG;IACH,OAAO,IAAI,IAAI;IAIf;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;;;OAIG;YACW,WAAW;IAwBzB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IAmBpB,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAoCd,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,CAAC,EACP,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IA4DnD,GAAG,CAAC,CAAC,EACT,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,IAAI,CAAC;IA0CV,MAAM,CAAC,CAAC,EACZ,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GACf,OAAO,CAAC,IAAI,CAAC;IA4CV,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCrD,KAAK,CAAC,CAAC,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,EACrB,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,EAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,GAChC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;IA2HnC,SAAS,CAAC,CAAC,CAAC,EACV,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,4BAA4B,CAAC,CAAC,CAAC,EACzC,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,MAAM,IAAI;IA6Eb,qBAAqB,CAAC,CAAC,CAAC,EACtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,EAC3C,MAAM,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,MAAM,IAAI;CA4Gd"}
@@ -1 +1 @@
1
- import{wrapCrudError as c,validateWithSchema as U,DoNotDevError as $,CRUD_OPERATORS as m,ERROR_CODES as O,filterVisibleFields as R,getVisibleFields as G}from"@donotdev/core";import{defaultFieldMapper as V}from"../fieldMapper";const Y="id";function N(u){const{createdAt:e,updatedAt:t,created_at:r,updated_at:i,...s}=u;return s}function D(u){if(/[(),]/.test(u))throw new Error("[crudAdapter] Invalid filter value: contains PostgREST operator characters");return u}function S(u,e){return typeof u=="string"?u:String(u)}function k(u,e,t){const{field:r,operator:i,value:s}=e,n=t(S(r,"where"));switch(i){case m.EQ:return u.eq(n,s);case m.NEQ:return u.neq(n,s);case m.LT:return u.lt(n,s);case m.LTE:return u.lte(n,s);case m.GT:return u.gt(n,s);case m.GTE:return u.gte(n,s);case m.IN:return u.in(n,Array.isArray(s)?s:[s]);case m.NOT_IN:return u.not(n,"in",Array.isArray(s)?s:[s]);case m.ARRAY_CONTAINS:return u.contains(n,s);case m.ARRAY_CONTAINS_ANY:if(!Array.isArray(s)||s.length===0)throw new $("SupabaseCrudAdapter: ARRAY_CONTAINS_ANY requires a non-empty array",O.INVALID_ARGUMENT,{context:{operator:i,field:r}});return u.overlaps(n,s);default:throw new $(`SupabaseCrudAdapter: unsupported operator "${i}"`,O.INVALID_ARGUMENT,{context:{operator:i,field:r}})}}class K{client;idColumn;dbLevelSecurity=!0;mapper;_roleCache=null;_unsubscribeAuthState;constructor(e,t=Y){this.client=e,this.idColumn=t,this.mapper=V;const{data:{subscription:r}}=this.client.auth.onAuthStateChange(()=>{this._roleCache=null});this._unsubscribeAuthState=()=>r.unsubscribe()}invalidateRoleCache(){this._roleCache=null}dispose(){this._unsubscribeAuthState()}normalize(e){return this.mapper.fromBackendRow(e)}async getUserRole(){const e=Date.now();if(this._roleCache&&e<this._roleCache.expiresAt)return this._roleCache.role;try{const{data:t}=await this.client.auth.getSession(),r=t?.session?.user?.app_metadata;let i="guest";return r&&(r.role==="super"||r.isSuper===!0?i="super":r.role==="admin"||r.isAdmin===!0?i="admin":r.role==="user"?i="user":i=r.role||"guest"),this._roleCache={role:i,expiresAt:e+3e4},i}catch{return"guest"}}buildSelectColumns(e,t){if(!e)return"*";try{const r=G(e,t);if(r.length===0)return"*";const i=new Set(r.map(s=>this.mapper.toBackendField(s)));return i.add(this.idColumn),i.add("status"),Array.from(i).join(",")}catch{return"*"}}async get(e,t,r){const i=r?await this.getUserRole():"guest",s=this.buildSelectColumns(r,i),{data:n,error:a}=await this.client.from(e).select(s).eq(this.idColumn,t).maybeSingle();if(a){if(a.code==="PGRST116"||a.message?.includes("No rows"))return null;throw c(a,"SupabaseCrudAdapter","get",e,t)}if(!n)return null;const l=n,o=String(l[this.idColumn]??t),f={...l,id:o},h=this.normalize(f);return r?{...R(h,r,i),id:o}:{...h,id:o}}async add(e,t,r){const i=r?U(r,t,"SupabaseCrudAdapter.add"):t,s=N(i);let n;try{const{data:C}=await this.client.auth.getSession();n=C?.session?.user?.id}catch(C){throw c(C instanceof Error?C:new Error(String(C)),"SupabaseCrudAdapter","add",e)}if(!n)throw c(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","add",e);const a={...s,createdById:n,updatedById:n},l=this.mapper.toBackendKeys(a),{data:o,error:f}=await this.client.from(e).insert(l).select().single();if(f)throw c(f,"SupabaseCrudAdapter","add",e);if(!o)throw c(new Error("Insert returned no data"),"SupabaseCrudAdapter","add",e);const h=String(o[this.idColumn]??""),b=this.normalize({...o,id:h});return{id:h,data:b}}async set(e,t,r,i){const s=i?U(i,r,"SupabaseCrudAdapter.set"):r;let n;try{const{data:o}=await this.client.auth.getSession();n=o?.session?.user?.id}catch(o){throw c(o instanceof Error?o:new Error(String(o)),"SupabaseCrudAdapter","set",e,t)}if(!n)throw c(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","set",e,t);const a=N({...s,[this.idColumn]:t,updatedById:n}),{error:l}=await this.client.from(e).upsert(this.mapper.toBackendKeys(a),{onConflict:this.idColumn});if(l)throw c(l,"SupabaseCrudAdapter","set",e,t)}async update(e,t,r){let i;try{const{data:a}=await this.client.auth.getSession();i=a?.session?.user?.id}catch(a){throw c(a instanceof Error?a:new Error(String(a)),"SupabaseCrudAdapter","update",e,t)}if(!i)throw c(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","update",e,t);const s=N({...r,updatedById:i}),{error:n}=await this.client.from(e).update(this.mapper.toBackendKeys(s)).eq(this.idColumn,t);if(n)throw c(n,"SupabaseCrudAdapter","update",e,t)}async delete(e,t){let r;try{const{data:s}=await this.client.auth.getSession();r=s?.session?.user?.id}catch(s){throw c(s instanceof Error?s:new Error(String(s)),"SupabaseCrudAdapter","delete",e,t)}if(!r)throw c(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","delete",e,t);const{error:i}=await this.client.from(e).delete().eq(this.idColumn,t);if(i)throw c(i,"SupabaseCrudAdapter","delete",e,t)}async query(e,t,r,i){const s=r?await this.getUserRole():null,n=r&&s?this.buildSelectColumns(r,s):"*";let a=this.client.from(e).select(n,{count:"exact"});const l=p=>this.mapper.toBackendField(p);if(t.where)for(const p of t.where)a=k(a,p,l);const o=t.orderBy?.[0],f=S(o?.field??this.idColumn,"orderBy"),h=l(f),b=o?.direction??"asc";if(t.orderBy&&t.orderBy.length>0)for(const p of t.orderBy){const w=l(S(p.field,"orderBy"));a=a.order(w,{ascending:(p.direction??"asc")==="asc"})}else a=a.order(this.idColumn,{ascending:!0});const C=t.limit??50,d=t.startAfter??null;let g;if(d){let p=this.client.from(e).select(n,{count:"exact",head:!0});if(t.where)for(const E of t.where)p=k(p,E,l);const w=await p,{count:I}=w;g=I??void 0,b==="asc"?a=a.gt(h,d):a=a.lt(h,d)}a=a.limit(C+1);const x=await a,{data:L,error:A,count:F}=x;if(A)throw c(A instanceof Error?A:new Error(A.message||String(A)),"SupabaseCrudAdapter","query",e);const _=L??[],v=_.length>C,T=v?_.slice(0,C):_,y=T[T.length-1],M=y!=null?String(y[h]??y[this.idColumn]??y.id??""):null,B=s,q=[];for(const p of T){const w=String(p[this.idColumn]??p.id??""),I={...p,id:w},E=this.normalize(I),z=r&&B?R(E,r,B):E;q.push({...z,id:w})}return{items:q,total:g??F??void 0,hasMore:v,lastVisible:M}}subscribe(e,t,r,i){const s=this.client.channel(`doc:${encodeURIComponent(e)}:${encodeURIComponent(t)}`);return s.on("postgres_changes",{event:"*",schema:"public",table:e,filter:`${this.idColumn}=eq.${D(t)}`},n=>{const a=n.new;if(!a){r(null);return}const l={...a,id:a[this.idColumn]??t},o=this.normalize(l);i?this.getUserRole().then(f=>{const h=R(o,i,f);r({...h,id:t})},()=>{const f=R(o,i,"guest");r({...f,id:t})}):r({...o,id:t})}).subscribe(n=>{(n==="CHANNEL_ERROR"||n==="TIMED_OUT")&&r(null,c(new Error(`Subscription error: ${n}`),"SupabaseCrudAdapter","subscribe",e,t))}),()=>{this.client.removeChannel(s)}}subscribeToCollection(e,t,r,i){const s=(t.where??[]).filter(d=>d.operator===m.EQ&&d.value!=null),n=d=>this.mapper.toBackendField(d);s.length>1;const a=s[0],l=a?`${n(S(a.field,"subscribeToCollection.where"))}=eq.${D(String(a.value))}`:void 0,o=s.length>0?s.map(d=>`${n(S(d.field,"subscribeToCollection.where"))}=eq.${encodeURIComponent(String(d.value))}`).join("&"):void 0,f=o?`col:${encodeURIComponent(e)}:${o}`:`col:${encodeURIComponent(e)}`,h=this.client.channel(f);let b=null;const C=()=>{b&&clearTimeout(b),b=setTimeout(()=>{this.query(e,t,i).then(d=>r(d.items),d=>{const g=d instanceof Error?d:new Error(String(d));r([],c(g,"SupabaseCrudAdapter","subscribeToCollection",e))})},100)};return h.on("postgres_changes",{event:"*",schema:"public",table:e,...l?{filter:l}:{}},C).subscribe(d=>{(d==="CHANNEL_ERROR"||d==="TIMED_OUT")&&r([],c(new Error(`Subscription error: ${d}`),"SupabaseCrudAdapter","subscribeToCollection",e))}),()=>{b&&clearTimeout(b),this.client.removeChannel(h)}}}export{K as SupabaseCrudAdapter};
1
+ import{wrapCrudError as l,validateWithSchema as $,DoNotDevError as M,CRUD_OPERATORS as m,ERROR_CODES as D,filterVisibleFields as R,getVisibleFields as Y}from"@donotdev/core";import{createEntityAwareMapper as G,defaultFieldMapper as P,getEntityFieldNames as Q}from"../fieldMapper";const W="id";function N(d){const{createdAt:t,updatedAt:e,created_at:r,updated_at:s,...n}=d;return n}function U(d){if(/[(),]/.test(d))throw new Error("[crudAdapter] Invalid filter value: contains PostgREST operator characters");return d}function y(d,t){return typeof d=="string"?d:String(d)}function O(d,t,e){const{field:r,operator:s,value:n}=t,o=e(y(r,"where"));switch(s){case m.EQ:return d.eq(o,n);case m.NEQ:return d.neq(o,n);case m.LT:return d.lt(o,n);case m.LTE:return d.lte(o,n);case m.GT:return d.gt(o,n);case m.GTE:return d.gte(o,n);case m.IN:return d.in(o,Array.isArray(n)?n:[n]);case m.NOT_IN:return d.not(o,"in",Array.isArray(n)?n:[n]);case m.ARRAY_CONTAINS:return d.contains(o,n);case m.ARRAY_CONTAINS_ANY:if(!Array.isArray(n)||n.length===0)throw new M("SupabaseCrudAdapter: ARRAY_CONTAINS_ANY requires a non-empty array",D.INVALID_ARGUMENT,{context:{operator:s,field:r}});return d.overlaps(o,n);default:throw new M(`SupabaseCrudAdapter: unsupported operator "${s}"`,D.INVALID_ARGUMENT,{context:{operator:s,field:r}})}}class H{client;idColumn;dbLevelSecurity=!0;mapper;_roleCache=null;_unsubscribeAuthState;constructor(t,e=W){this.client=t,this.idColumn=e,this.mapper=P;const{data:{subscription:r}}=this.client.auth.onAuthStateChange(()=>{this._roleCache=null});this._unsubscribeAuthState=()=>r.unsubscribe()}invalidateRoleCache(){this._roleCache=null}dispose(){this._unsubscribeAuthState()}createEntityMapper(t){const e=Q(t);return e.length===0?this.mapper:G(e)}async getUserRole(){const t=Date.now();if(this._roleCache&&t<this._roleCache.expiresAt)return this._roleCache.role;try{const{data:e}=await this.client.auth.getSession(),r=e?.session?.user?.app_metadata;let s="guest";return r&&(r.role==="super"||r.isSuper===!0?s="super":r.role==="admin"||r.isAdmin===!0?s="admin":r.role==="user"?s="user":s=r.role||"guest"),this._roleCache={role:s,expiresAt:t+3e4},s}catch{return"guest"}}buildSelectColumns(t,e){if(!t)return"*";try{const r=Y(t,e);if(r.length===0)return"*";const s=new Set(r.map(n=>this.mapper.toBackendField(n)));return s.add(this.idColumn),s.add("status"),Array.from(s).join(",")}catch{return"*"}}async get(t,e,r){const s=r?await this.getUserRole():"guest",n=this.buildSelectColumns(r,s),{data:o,error:a}=await this.client.from(t).select(n).eq(this.idColumn,e).maybeSingle();if(a){if(a.code==="PGRST116"||a.message?.includes("No rows"))return null;throw l(a,"SupabaseCrudAdapter","get",t,e)}if(!o)return null;const c=o,i=String(c[this.idColumn]??e),p={...c,id:i},f=this.createEntityMapper(r).fromBackendRow(p);return r?{...R(f,r,s),id:i}:{...f,id:i}}async add(t,e,r){const s=r?$(r,e,"SupabaseCrudAdapter.add"):e,n=N(s);let o;try{const{data:w}=await this.client.auth.getSession();o=w?.session?.user?.id}catch(w){throw l(w instanceof Error?w:new Error(String(w)),"SupabaseCrudAdapter","add",t)}if(!o)throw l(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","add",t);const a={...n,createdById:o,updatedById:o},c=this.mapper.toBackendKeys(a),{data:i,error:p}=await this.client.from(t).insert(c).select().single();if(p)throw l(p,"SupabaseCrudAdapter","add",t);if(!i)throw l(new Error("Insert returned no data"),"SupabaseCrudAdapter","add",t);const h=String(i[this.idColumn]??""),f=this.mapper.fromBackendRow({...i,id:h});return{id:h,data:f}}async set(t,e,r,s){const n=s?$(s,r,"SupabaseCrudAdapter.set"):r;let o;try{const{data:i}=await this.client.auth.getSession();o=i?.session?.user?.id}catch(i){throw l(i instanceof Error?i:new Error(String(i)),"SupabaseCrudAdapter","set",t,e)}if(!o)throw l(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","set",t,e);const a=N({...n,[this.idColumn]:e,updatedById:o}),{error:c}=await this.client.from(t).upsert(this.mapper.toBackendKeys(a),{onConflict:this.idColumn});if(c)throw l(c,"SupabaseCrudAdapter","set",t,e)}async update(t,e,r){let s;try{const{data:a}=await this.client.auth.getSession();s=a?.session?.user?.id}catch(a){throw l(a instanceof Error?a:new Error(String(a)),"SupabaseCrudAdapter","update",t,e)}if(!s)throw l(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","update",t,e);const n=N({...r,updatedById:s}),{error:o}=await this.client.from(t).update(this.mapper.toBackendKeys(n)).eq(this.idColumn,e);if(o)throw l(o,"SupabaseCrudAdapter","update",t,e)}async delete(t,e){let r;try{const{data:n}=await this.client.auth.getSession();r=n?.session?.user?.id}catch(n){throw l(n instanceof Error?n:new Error(String(n)),"SupabaseCrudAdapter","delete",t,e)}if(!r)throw l(new Error("Authentication required for this operation"),"SupabaseCrudAdapter","delete",t,e);const{error:s}=await this.client.from(t).delete().eq(this.idColumn,e);if(s)throw l(s,"SupabaseCrudAdapter","delete",t,e)}async query(t,e,r,s){const n=r?await this.getUserRole():null,o=r&&n?this.buildSelectColumns(r,n):"*";let a=this.client.from(t).select(o,{count:"exact"});const c=C=>this.mapper.toBackendField(C);if(e.where)for(const C of e.where)a=O(a,C,c);const i=e.orderBy?.[0],p=y(i?.field??this.idColumn,"orderBy"),h=c(p),f=i?.direction??"asc";if(e.orderBy&&e.orderBy.length>0)for(const C of e.orderBy){const b=c(y(C.field,"orderBy"));a=a.order(b,{ascending:(C.direction??"asc")==="asc"})}else a=a.order(this.idColumn,{ascending:!0});const w=e.limit??50,u=e.startAfter??null;let g;if(u){let C=this.client.from(t).select(o,{count:"exact",head:!0});if(e.where)for(const E of e.where)C=O(C,E,c);const b=await C,{count:T}=b;g=T??void 0,f==="asc"?a=a.gt(h,u):a=a.lt(h,u)}a=a.limit(w+1);const q=await a,{data:k,error:A,count:x}=q;if(A)throw l(A instanceof Error?A:new Error(A.message||String(A)),"SupabaseCrudAdapter","query",t);const _=k??[],B=_.length>w,I=B?_.slice(0,w):_,S=I[I.length-1],L=S!=null?String(S[h]??S[this.idColumn]??S.id??""):null,F=n,z=this.createEntityMapper(r),v=[];for(const C of I){const b=String(C[this.idColumn]??C.id??""),T={...C,id:b},E=z.fromBackendRow(T),V=r&&F?R(E,r,F):E;v.push({...V,id:b})}return{items:v,total:g??x??void 0,hasMore:B,lastVisible:L}}subscribe(t,e,r,s){const n=this.client.channel(`doc:${encodeURIComponent(t)}:${encodeURIComponent(e)}`),o=this.createEntityMapper(s);return n.on("postgres_changes",{event:"*",schema:"public",table:t,filter:`${this.idColumn}=eq.${U(e)}`},a=>{const c=a.new;if(!c){r(null);return}const i={...c,id:c[this.idColumn]??e};if(s)this.getUserRole().then(p=>{const h=o.fromBackendRow(i),f=R(h,s,p);r({...f,id:e})},()=>{const p=o.fromBackendRow(i),h=R(p,s,"guest");r({...h,id:e})});else{const p=o.fromBackendRow(i);r({...p,id:e})}}).subscribe(a=>{(a==="CHANNEL_ERROR"||a==="TIMED_OUT")&&r(null,l(new Error(`Subscription error: ${a}`),"SupabaseCrudAdapter","subscribe",t,e))}),()=>{this.client.removeChannel(n)}}subscribeToCollection(t,e,r,s){const n=(e.where??[]).filter(u=>u.operator===m.EQ&&u.value!=null),o=u=>this.mapper.toBackendField(u);n.length>1;const a=n[0],c=a?`${o(y(a.field,"subscribeToCollection.where"))}=eq.${U(String(a.value))}`:void 0,i=n.length>0?n.map(u=>`${o(y(u.field,"subscribeToCollection.where"))}=eq.${encodeURIComponent(String(u.value))}`).join("&"):void 0,p=i?`col:${encodeURIComponent(t)}:${i}`:`col:${encodeURIComponent(t)}`,h=this.client.channel(p);let f=null;const w=()=>{f&&clearTimeout(f),f=setTimeout(()=>{this.query(t,e,s).then(u=>r(u.items),u=>{const g=u instanceof Error?u:new Error(String(u));r([],l(g,"SupabaseCrudAdapter","subscribeToCollection",t))})},100)};return h.on("postgres_changes",{event:"*",schema:"public",table:t,...c?{filter:c}:{}},w).subscribe(u=>{(u==="CHANNEL_ERROR"||u==="TIMED_OUT")&&r([],l(new Error(`Subscription error: ${u}`),"SupabaseCrudAdapter","subscribeToCollection",t))}),()=>{f&&clearTimeout(f),this.client.removeChannel(h)}}}export{H as SupabaseCrudAdapter};
@@ -1 +1 @@
1
- import{SupabaseCallableProvider as a}from"./callableProvider";import{SupabaseCrudAdapter as r}from"./crudAdapter";import{SupabaseStorageAdapter as e}from"./storageAdapter";import{SupabaseAuth as p}from"./auth";export{p as SupabaseAuth,a as SupabaseCallableProvider,r as SupabaseCrudAdapter,e as SupabaseStorageAdapter};
1
+ import{SupabaseCallableProvider as e}from"./callableProvider";import{SupabaseCrudAdapter as p}from"./crudAdapter";import{SupabaseStorageAdapter as u}from"./storageAdapter";import{SupabaseAuth as S}from"./auth";export{S as SupabaseAuth,e as SupabaseCallableProvider,p as SupabaseCrudAdapter,u as SupabaseStorageAdapter};
@@ -1 +1 @@
1
- {"version":3,"file":"storageAdapter.d.ts","sourceRoot":"","sources":["../../src/client/storageAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,MAAuB;IAG5C,MAAM,CACV,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC;IAiClB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,OAAO,CAAC,WAAW;CA8BpB"}
1
+ {"version":3,"file":"storageAdapter.d.ts","sourceRoot":"","sources":["../../src/client/storageAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAE1D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,cAAc,EACtB,MAAM,GAAE,MAAuB;IAG5C,MAAM,CACV,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC;IA6ClB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,OAAO,CAAC,WAAW;CAoCpB"}
@@ -1 +1 @@
1
- import{wrapStorageError as r}from"@donotdev/core";const i="uploads";class h{client;bucket;constructor(e,t=i){this.client=e,this.bucket=t}async upload(e,t){try{t?.onProgress?.(0);const a=t?.storagePath??"",l=e instanceof File&&e.name?.includes(".")?e.name.slice(e.name.lastIndexOf(".")):"",n=t?.filename??`${Date.now()}-${Math.random().toString(36).slice(2,10)}${l}`,o=a?`${a}/${n}`:n,{data:s,error:c}=await this.client.storage.from(this.bucket).upload(o,e,{upsert:!0});if(c)throw r(c,"SupabaseStorageAdapter","upload",o);if(!s)throw r(new Error("Upload returned no data"),"SupabaseStorageAdapter","upload",o);t?.onProgress?.(100);const{data:{publicUrl:p}}=this.client.storage.from(this.bucket).getPublicUrl(s.path);return{url:p,path:s.path}}catch(a){throw r(a,"SupabaseStorageAdapter","upload",t?.storagePath||"")}}async delete(e){try{const t=e.startsWith("http")?this.pathFromUrl(e):e,{error:a}=await this.client.storage.from(this.bucket).remove([t]);if(a)throw r(a,"SupabaseStorageAdapter","delete",t)}catch(t){throw r(t,"SupabaseStorageAdapter","delete",e)}}async getUrl(e){const{data:{publicUrl:t}}=this.client.storage.from(this.bucket).getPublicUrl(e);return t}pathFromUrl(e){try{const t=new URL(e);let a=t.pathname.match(/\/storage\/v1\/object\/public\/[^/]+\/(.+)/);return a&&a[1]!=null||(a=t.pathname.match(/\/storage\/v1\/object\/sign\/[^/]+\/(.+)/),a&&a[1]!=null)?decodeURIComponent(a[1]):t.pathname&&t.pathname.length>1&&!t.pathname.startsWith("/api/")?decodeURIComponent(t.pathname.slice(1)):e}catch{return e}}}export{h as SupabaseStorageAdapter};
1
+ import{wrapStorageError as r}from"@donotdev/core";const i="uploads";class d{client;bucket;constructor(e,t=i){this.client=e,this.bucket=t}async upload(e,t){try{t?.onProgress?.(0);const a=t?.storagePath??"",h=e instanceof File&&e.name?.includes(".")?e.name.slice(e.name.lastIndexOf(".")):"",s=t?.filename??`${Date.now()}-${Math.random().toString(36).slice(2,10)}${h}`,o=a?`${a}/${s}`:s,{data:n,error:c}=await this.client.storage.from(this.bucket).upload(o,e,{upsert:!0});if(c)throw r(c,"SupabaseStorageAdapter","upload",o);if(!n)throw r(new Error("Upload returned no data"),"SupabaseStorageAdapter","upload",o);t?.onProgress?.(100);const{data:{publicUrl:p}}=this.client.storage.from(this.bucket).getPublicUrl(n.path);return{url:p,path:n.path}}catch(a){throw r(a,"SupabaseStorageAdapter","upload",t?.storagePath||"")}}async delete(e){try{const t=e.startsWith("http")?this.pathFromUrl(e):e,{error:a}=await this.client.storage.from(this.bucket).remove([t]);if(a)throw r(a,"SupabaseStorageAdapter","delete",t)}catch(t){throw r(t,"SupabaseStorageAdapter","delete",e)}}async getUrl(e){const{data:{publicUrl:t}}=this.client.storage.from(this.bucket).getPublicUrl(e);return t}pathFromUrl(e){try{const t=new URL(e);let a=t.pathname.match(/\/storage\/v1\/object\/public\/[^/]+\/(.+)/);return a&&a[1]!=null||(a=t.pathname.match(/\/storage\/v1\/object\/sign\/[^/]+\/(.+)/),a&&a[1]!=null)?decodeURIComponent(a[1]):t.pathname&&t.pathname.length>1&&!t.pathname.startsWith("/api/")?decodeURIComponent(t.pathname.slice(1)):e}catch{return e}}}export{d as SupabaseStorageAdapter};
@@ -8,4 +8,26 @@ export interface SupabaseFieldMapper {
8
8
  }
9
9
  /** Default mapper (camelToSnake) for use by adapters and edge functions */
10
10
  export declare const defaultFieldMapper: SupabaseFieldMapper;
11
+ /**
12
+ * Extract entity field names from a Valibot schema.
13
+ * Works with any schema that has an `entries` property (object schemas).
14
+ * Returns empty array if schema is missing or has no entries.
15
+ *
16
+ * @param schema - Valibot schema (or undefined)
17
+ * @returns Array of entity field name strings
18
+ */
19
+ export declare function getEntityFieldNames(schema: unknown): string[];
20
+ /**
21
+ * Entity-aware mapper factory. Builds a reverse map from DB column (snake_case)
22
+ * back to the entity field name as defined in the schema.
23
+ *
24
+ * This ensures `fromBackendRow` returns keys that match entity field names —
25
+ * so `filterVisibleFields` can find them regardless of whether the entity
26
+ * uses snake_case (`first_name`) or camelCase (`firstName`) field names.
27
+ *
28
+ * Write paths (`toBackendField`, `toBackendKeys`) are shared with the default mapper.
29
+ *
30
+ * @param entityFieldNames - Field names from the entity schema (use `getEntityFieldNames(schema)`)
31
+ */
32
+ export declare function createEntityAwareMapper(entityFieldNames: string[]): SupabaseFieldMapper;
11
33
  //# sourceMappingURL=fieldMapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fieldMapper.d.ts","sourceRoot":"","sources":["../src/fieldMapper.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,kEAAkE;IAClE,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,uEAAuE;IACvE,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvE;AAiCD,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,qBAA8B,CAAC"}
1
+ {"version":3,"file":"fieldMapper.d.ts","sourceRoot":"","sources":["../src/fieldMapper.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7C,kEAAkE;IAClE,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,uEAAuE;IACvE,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvE;AAqCD,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,qBAA8B,CAAC;AAY9D;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,CAK7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,MAAM,EAAE,GACzB,mBAAmB,CAyBrB"}
@@ -1 +1 @@
1
- function a(t){return typeof t!="string"?String(t):t.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").toLowerCase()}function i(t){return typeof t!="string"?String(t):t.replace(/_([a-z])/g,(e,r)=>r.toUpperCase())}const d=new Set(["createdAt","updatedAt"]);function s(t){if(t instanceof Date)return t.toISOString();if(typeof t=="string"){if(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(t))return t;if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t))return new Date(t.replace(" ","T")).toISOString()}return t}function c(){return{toBackendField:t=>{if(typeof t!="string")throw new TypeError(`Supabase field mapper: field name must be a string (e.g. "createdById"), got ${typeof t}. Check where query options (orderBy/where) are built \u2014 ensure "field" is the field name string, not a schema or other value.`);return a(t)},toBackendKeys:t=>{const e={};for(const[r,n]of Object.entries(t))e[a(r)]=n;return e},fromBackendRow:t=>{const e={};for(const[r,n]of Object.entries(t)){const o=i(r);e[o]=d.has(o)?s(n):n}return e}}}const f=c();export{f as defaultFieldMapper};
1
+ function d(e){return typeof e!="string"?String(e):e.replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").toLowerCase()}function i(e){return typeof e!="string"?String(e):e.replace(/_([a-z])/g,(r,t)=>t.toUpperCase())}const f=new Set(["createdAt","updatedAt"]);function u(e){if(e instanceof Date)return e.toISOString();if(typeof e=="string"){if(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(e))return e;if(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e))return new Date(e.replace(" ","T")).toISOString()}return e}function y(){return{toBackendField:n=>{if(typeof n!="string")throw new TypeError(`Supabase field mapper: field name must be a string (e.g. "createdById"), got ${typeof n}. Check where query options (orderBy/where) are built \u2014 ensure "field" is the field name string, not a schema or other value.`);return d(n)},toBackendKeys:n=>{const o={};for(const[a,c]of Object.entries(n))o[d(a)]=c;return o},fromBackendRow:n=>{const o={};for(const[a,c]of Object.entries(n)){const s=i(a);o[s]=f.has(s)?u(c):c}return o}}}const p=y(),g=["id","createdAt","updatedAt","createdById","updatedById","status"];function k(e){if(!e||typeof e!="object")return[];const r=e.entries;return!r||typeof r!="object"?[]:Object.keys(r)}function l(e){const r=new Map;for(const t of e)r.set(d(t),t);for(const t of g)r.set(d(t),t);return{toBackendField:p.toBackendField,toBackendKeys:p.toBackendKeys,fromBackendRow:t=>{const n={};for(const[o,a]of Object.entries(t)){const c=r.get(o)??i(o);n[c]=f.has(c)?u(a):a}return n}}}export{l as createEntityAwareMapper,p as defaultFieldMapper,k as getEntityFieldNames};
package/dist/index.d.ts CHANGED
@@ -5,5 +5,5 @@
5
5
  * @packageDocumentation
6
6
  */
7
7
  export * from './client';
8
- export { defaultFieldMapper, type SupabaseFieldMapper, } from './fieldMapper';
8
+ export { createEntityAwareMapper, defaultFieldMapper, getEntityFieldNames, type SupabaseFieldMapper, } from './fieldMapper';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./client";import{defaultFieldMapper as e}from"./fieldMapper";export{e as defaultFieldMapper};
1
+ export*from"./client";import{createEntityAwareMapper as a,defaultFieldMapper as p,getEntityFieldNames as i}from"./fieldMapper";export{a as createEntityAwareMapper,p as defaultFieldMapper,i as getEntityFieldNames};
@@ -1 +1 @@
1
- {"version":3,"file":"authAdapter.d.ts","sourceRoot":"","sources":["../../src/server/authAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,cAAc,CAOhB;AAMD;;;;;;;GAOG;AACH,qBAAa,yBAA0B,YAAW,kBAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmClD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA0BtD,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC;CAwBjB"}
1
+ {"version":3,"file":"authAdapter.d.ts","sourceRoot":"","sources":["../../src/server/authAdapter.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO5D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,cAAc,CAOhB;AAMD;;;;;;;GAOG;AACH,qBAAa,yBAA0B,YAAW,kBAAkB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAE7C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAwClD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA0BtD,eAAe,CACnB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,IAAI,CAAC;CAmCjB"}
@@ -1 +1 @@
1
- import{wrapAuthError as s,DoNotDevError as o}from"@donotdev/core";import{createClient as u}from"@supabase/supabase-js";function c(i,t){return u(i,t,{auth:{autoRefreshToken:!1,persistSession:!1}})}class d{client;constructor(t){this.client=t}async verifyToken(t){try{const{data:{user:r},error:e}=await this.client.auth.getUser(t);if(e){const a=e instanceof Error?e:new Error(e.message||e.error_description||String(e));throw s(a,"SupabaseServerAuthAdapter","verifyToken")}if(!r)throw s(new Error("Invalid token"),"SupabaseServerAuthAdapter","verifyToken");return{uid:r.id,email:r.email??void 0,claims:{...r.user_metadata,...r.app_metadata}}}catch(r){throw r instanceof o?r:s(r,"SupabaseServerAuthAdapter","verifyToken")}}async getUser(t){const{data:{user:r},error:e}=await this.client.auth.admin.getUserById(t);if(e||!r)return null;const a=r.user_metadata??{},n=typeof a.full_name=="string"?a.full_name:typeof a.name=="string"?a.name:void 0;return{uid:r.id,email:r.email??void 0,displayName:n,customClaims:{...r.user_metadata,...r.app_metadata}}}async setCustomClaims(t,r){try{const{error:e}=await this.client.auth.admin.updateUserById(t,{app_metadata:r});if(e){const a=e instanceof Error?e:new Error(e.message||e.error_description||String(e));throw s(a,"SupabaseServerAuthAdapter","setCustomClaims",{uid:t})}}catch(e){throw e instanceof o?e:s(e,"SupabaseServerAuthAdapter","setCustomClaims",{uid:t})}}}export{d as SupabaseServerAuthAdapter,c as createServerClient};
1
+ import{wrapAuthError as s,DoNotDevError as i}from"@donotdev/core";import{createClient as u}from"@supabase/supabase-js";function d(n,t){return u(n,t,{auth:{autoRefreshToken:!1,persistSession:!1}})}class p{client;constructor(t){this.client=t}async verifyToken(t){try{const{data:{user:r},error:e}=await this.client.auth.getUser(t);if(e){const a=e instanceof Error?e:new Error(e.message||e.error_description||String(e));throw s(a,"SupabaseServerAuthAdapter","verifyToken")}if(!r)throw s(new Error("Invalid token"),"SupabaseServerAuthAdapter","verifyToken");return{uid:r.id,email:r.email??void 0,claims:{...r.user_metadata,...r.app_metadata}}}catch(r){throw r instanceof i?r:s(r,"SupabaseServerAuthAdapter","verifyToken")}}async getUser(t){const{data:{user:r},error:e}=await this.client.auth.admin.getUserById(t);if(e||!r)return null;const a=r.user_metadata??{},o=typeof a.full_name=="string"?a.full_name:typeof a.name=="string"?a.name:void 0;return{uid:r.id,email:r.email??void 0,displayName:o,customClaims:{...r.user_metadata,...r.app_metadata}}}async setCustomClaims(t,r){try{const{error:e}=await this.client.auth.admin.updateUserById(t,{app_metadata:r});if(e){const a=e instanceof Error?e:new Error(e.message||e.error_description||String(e));throw s(a,"SupabaseServerAuthAdapter","setCustomClaims",{uid:t})}}catch(e){throw e instanceof i?e:s(e,"SupabaseServerAuthAdapter","setCustomClaims",{uid:t})}}}export{p as SupabaseServerAuthAdapter,d as createServerClient};
@@ -1 +1 @@
1
- import{SupabaseServerAuthAdapter as e,createServerClient as r}from"./authAdapter";export{e as SupabaseServerAuthAdapter,r as createServerClient};
1
+ import{SupabaseServerAuthAdapter as t,createServerClient as a}from"./authAdapter";export{t as SupabaseServerAuthAdapter,a as createServerClient};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donotdev/supabase",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE.md",