learn-auth-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,170 @@
1
+ import * as better_auth from 'better-auth';
2
+
3
+ interface AuthSDKConfig {
4
+ tenantUrl: string;
5
+ }
6
+ interface User {
7
+ id: string;
8
+ email: string;
9
+ name?: string;
10
+ avatarUrl?: string;
11
+ role?: string;
12
+ roles?: string[];
13
+ }
14
+ interface Session {
15
+ user: User;
16
+ session: {
17
+ id: string;
18
+ expiresAt: Date;
19
+ };
20
+ }
21
+
22
+ declare class AuthSDK {
23
+ private client;
24
+ constructor(config: AuthSDKConfig);
25
+ signIn(email: string, password: string): Promise<{
26
+ data: Omit<{
27
+ redirect: boolean;
28
+ token: string;
29
+ url?: string | undefined;
30
+ user: {
31
+ id: string;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ email: string;
35
+ emailVerified: boolean;
36
+ name: string;
37
+ image?: string | null | undefined | undefined;
38
+ };
39
+ }, "user"> & {
40
+ user: better_auth.StripEmptyObjects<{
41
+ id: string;
42
+ createdAt: Date;
43
+ updatedAt: Date;
44
+ email: string;
45
+ emailVerified: boolean;
46
+ name: string;
47
+ image?: string | null | undefined;
48
+ }>;
49
+ };
50
+ error: null;
51
+ } | {
52
+ data: null;
53
+ error: {
54
+ code?: string | undefined | undefined;
55
+ message?: string | undefined | undefined;
56
+ status: number;
57
+ statusText: string;
58
+ };
59
+ }>;
60
+ signUp(email: string, password: string, name: string): Promise<{
61
+ data: (Omit<{
62
+ token: null;
63
+ user: {
64
+ id: string;
65
+ createdAt: Date;
66
+ updatedAt: Date;
67
+ email: string;
68
+ emailVerified: boolean;
69
+ name: string;
70
+ image?: string | null | undefined | undefined;
71
+ };
72
+ }, "user"> & {
73
+ user: better_auth.StripEmptyObjects<{
74
+ id: string;
75
+ createdAt: Date;
76
+ updatedAt: Date;
77
+ email: string;
78
+ emailVerified: boolean;
79
+ name: string;
80
+ image?: string | null | undefined;
81
+ }>;
82
+ }) | (Omit<{
83
+ token: string;
84
+ user: {
85
+ id: string;
86
+ createdAt: Date;
87
+ updatedAt: Date;
88
+ email: string;
89
+ emailVerified: boolean;
90
+ name: string;
91
+ image?: string | null | undefined | undefined;
92
+ };
93
+ }, "user"> & {
94
+ user: better_auth.StripEmptyObjects<{
95
+ id: string;
96
+ createdAt: Date;
97
+ updatedAt: Date;
98
+ email: string;
99
+ emailVerified: boolean;
100
+ name: string;
101
+ image?: string | null | undefined;
102
+ }>;
103
+ });
104
+ error: null;
105
+ } | {
106
+ data: null;
107
+ error: {
108
+ code?: string | undefined | undefined;
109
+ message?: string | undefined | undefined;
110
+ status: number;
111
+ statusText: string;
112
+ };
113
+ }>;
114
+ signOut(): Promise<{
115
+ data: {
116
+ success: boolean;
117
+ };
118
+ error: null;
119
+ } | {
120
+ data: null;
121
+ error: {
122
+ code?: string | undefined | undefined;
123
+ message?: string | undefined | undefined;
124
+ status: number;
125
+ statusText: string;
126
+ };
127
+ }>;
128
+ getSession(): Promise<{
129
+ data: {
130
+ user: better_auth.StripEmptyObjects<{
131
+ id: string;
132
+ createdAt: Date;
133
+ updatedAt: Date;
134
+ email: string;
135
+ emailVerified: boolean;
136
+ name: string;
137
+ image?: string | null | undefined;
138
+ }>;
139
+ session: better_auth.StripEmptyObjects<{
140
+ id: string;
141
+ createdAt: Date;
142
+ updatedAt: Date;
143
+ userId: string;
144
+ expiresAt: Date;
145
+ token: string;
146
+ ipAddress?: string | null | undefined;
147
+ userAgent?: string | null | undefined;
148
+ }>;
149
+ } | null;
150
+ error: null;
151
+ } | {
152
+ data: null;
153
+ error: {
154
+ code?: string | undefined | undefined;
155
+ message?: string | undefined | undefined;
156
+ status: number;
157
+ statusText: string;
158
+ };
159
+ }>;
160
+ /**
161
+ * Check if the current user has a specific role
162
+ */
163
+ hasRole(role: string): Promise<boolean>;
164
+ /**
165
+ * Get all roles for the current user
166
+ */
167
+ getRoles(): Promise<string[]>;
168
+ }
169
+
170
+ export { AuthSDK, type AuthSDKConfig, type Session, type User };
@@ -0,0 +1,3 @@
1
+ "use strict";var AuthSDK=(()=>{var X=Object.defineProperty;var Ge=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var ze=Object.prototype.hasOwnProperty;var Je=(e,t)=>{for(var r in t)X(e,r,{get:t[r],enumerable:!0})},Qe=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $e(t))!ze.call(e,o)&&o!==r&&X(e,o,{get:()=>t[o],enumerable:!(n=Ge(t,o))||n.enumerable});return e};var Xe=e=>Qe(X({},"__esModule",{value:!0}),e);var Qt={};Je(Qt,{AuthSDK:()=>fe});var pe="1.6.9";var he=pe;var K=Symbol.for("better-auth:broadcast-channel"),Ke=()=>Math.floor(Date.now()/1e3),Ze=class{listeners=new Set;name;constructor(e="better-auth.message"){this.name=e}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}post(e){if(!(typeof window>"u"))try{localStorage.setItem(this.name,JSON.stringify({...e,timestamp:Ke()}))}catch{}}setup(){if(typeof window>"u"||typeof window.addEventListener>"u")return()=>{};let e=t=>{if(t.key!==this.name)return;let r=JSON.parse(t.newValue??"{}");r?.event!=="session"||!r?.data||this.listeners.forEach(n=>n(r))};return window.addEventListener("storage",e),()=>{window.removeEventListener("storage",e)}}};function q(e="better-auth.message"){return globalThis[K]||(globalThis[K]=new Ze(e)),globalThis[K]}var Z=Symbol.for("better-auth:focus-manager"),et=class{listeners=new Set;subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setFocused(e){this.listeners.forEach(t=>t(e))}setup(){if(typeof window>"u"||typeof document>"u"||typeof window.addEventListener>"u")return()=>{};let e=()=>{document.visibilityState==="visible"&&this.setFocused(!0)};return document.addEventListener("visibilitychange",e,!1),()=>{document.removeEventListener("visibilitychange",e,!1)}}};function ee(){return globalThis[Z]||(globalThis[Z]=new et),globalThis[Z]}var te=Symbol.for("better-auth:online-manager"),tt=class{listeners=new Set;isOnline=typeof navigator<"u"?navigator.onLine:!0;subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}setOnline(e){this.isOnline=e,this.listeners.forEach(t=>t(e))}setup(){if(typeof window>"u"||typeof window.addEventListener>"u")return()=>{};let e=()=>this.setOnline(!0),t=()=>this.setOnline(!1);return window.addEventListener("online",e,!1),window.addEventListener("offline",t,!1),()=>{window.removeEventListener("online",e,!1),window.removeEventListener("offline",t,!1)}}};function W(){return globalThis[te]||(globalThis[te]=new tt),globalThis[te]}var rt={proto:/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,constructor:/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,protoShort:/"__proto__"\s*:/,constructorShort:/"constructor"\s*:/},nt=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/,me={true:!0,false:!1,null:null,undefined:void 0,nan:NaN,infinity:Number.POSITIVE_INFINITY,"-infinity":Number.NEGATIVE_INFINITY},ot=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;function st(e){return e instanceof Date&&!isNaN(e.getTime())}function it(e){let t=ot.exec(e);if(!t)return null;let[,r,n,o,s,i,c,a,u,l,d]=t,p=new Date(Date.UTC(parseInt(r,10),parseInt(n,10)-1,parseInt(o,10),parseInt(s,10),parseInt(i,10),parseInt(c,10),a?parseInt(a.padEnd(3,"0"),10):0));if(u){let E=(parseInt(l,10)*60+parseInt(d,10))*(u==="+"?-1:1);p.setUTCMinutes(p.getUTCMinutes()+E)}return st(p)?p:null}function at(e,t={}){let{strict:r=!1,warnings:n=!1,reviver:o,parseDates:s=!0}=t;if(typeof e!="string")return e;let i=e.trim();if(i.length>0&&i[0]==='"'&&i.endsWith('"')&&!i.slice(1,-1).includes('"'))return i.slice(1,-1);let c=i.toLowerCase();if(c.length<=9&&c in me)return me[c];if(!nt.test(i)){if(r)throw new SyntaxError("[better-json] Invalid JSON");return e}if(Object.entries(rt).some(([a,u])=>{let l=u.test(i);return l&&n&&console.warn(`[better-json] Detected potential prototype pollution attempt using ${a} pattern`),l})&&r)throw new Error("[better-json] Potential prototype pollution attempt detected");try{return JSON.parse(i,(u,l)=>{if(u==="__proto__"||u==="constructor"&&l&&typeof l=="object"&&"prototype"in l){n&&console.warn(`[better-json] Dropping "${u}" key to prevent prototype pollution`);return}if(s&&typeof l=="string"){let d=it(l);if(d)return d}return o?o(u,l):l})}catch(a){if(r)throw a;return e}}function Ee(e,t={strict:!0}){return at(e,t)}var k=Symbol("clean");var v=[],I=0,V=4,lt=globalThis.nanostoresGlobal||={epoch:0},B=e=>{let t=[],r={get(){return r.lc||r.listen(()=>{})(),r.value},init:e,lc:0,listen(n){return r.lc=t.push(n),()=>{for(let s=I+V;s<v.length;)v[s]===n?v.splice(s,V):s+=V;let o=t.indexOf(n);~o&&(t.splice(o,1),--r.lc||r.off())}},notify(n,o){lt.epoch++;let s=!v.length;for(let i of t)v.push(i,r.value,n,o);if(s){for(I=0;I<v.length;I+=V)v[I](v[I+1],v[I+2],v[I+3]);v.length=0}},off(){},set(n){let o=r.value;o!==n&&(r.value=n,r.notify(o))},subscribe(n){let o=r.listen(n);return n(r.value),o},value:e};return process.env.NODE_ENV!=="production"&&(r[k]=()=>{t=[],r.lc=0,r.off()}),r};var ut=5,M=6,G=10,ct=(e,t,r,n)=>(e.events=e.events||{},e.events[r+G]||(e.events[r+G]=n(o=>{e.events[r].reduceRight((s,i)=>(i(s),s),{shared:{},...o})})),e.events[r]=e.events[r]||[],e.events[r].push(t),()=>{let o=e.events[r],s=o.indexOf(t);o.splice(s,1),o.length||(delete e.events[r],e.events[r+G](),delete e.events[r+G])});var _e=1e3,Y=(e,t)=>ct(e,n=>{let o=t(n);o&&e.events[M].push(o)},ut,n=>{let o=e.listen;e.listen=(...i)=>(!e.lc&&!e.active&&(e.active=!0,n()),o(...i));let s=e.off;if(e.events[M]=[],e.off=()=>{s(),setTimeout(()=>{if(e.active&&!e.lc){e.active=!1;for(let i of e.events[M])i();e.events[M]=[]}},_e)},process.env.NODE_ENV!=="production"){let i=e[k];e[k]=()=>{for(let c of e.events[M])c();e.events[M]=[],e.active=!1,i()}}return()=>{e.listen=o,e.off=s}});var ft=()=>typeof window>"u",Re=(e,t,r,n)=>{let o=B({data:null,error:null,isPending:!0,isRefetching:!1,refetch:c=>s(c)}),s=async c=>new Promise(a=>{let u=typeof n=="function"?n({data:o.get().data,error:o.get().error,isPending:o.get().isPending}):n;r(t,{...u,query:{...u?.query,...c?.query},async onSuccess(l){o.set({data:l.data,error:null,isPending:!1,isRefetching:!1,refetch:o.value.refetch}),await u?.onSuccess?.(l)},async onError(l){let{request:d}=l,p=typeof d.retry=="number"?d.retry:d.retry?.attempts,E=d.retryAttempt||0;if(p&&E<p)return;let y=l.error.status===401;o.set({error:l.error,data:y?null:o.get().data,isPending:!1,isRefetching:!1,refetch:o.value.refetch}),await u?.onError?.(l)},async onRequest(l){let d=o.get();o.set({isPending:d.data===null,data:d.data,error:null,isRefetching:!0,refetch:o.value.refetch}),await u?.onRequest?.(l)}}).catch(l=>{o.set({error:l,data:o.get().data,isPending:!1,isRefetching:!1,refetch:o.value.refetch})}).finally(()=>{a(void 0)})});e=Array.isArray(e)?e:[e];let i=!1;for(let c of e)c.subscribe(async()=>{ft()||(i?await s():Y(o,()=>{let a=setTimeout(async()=>{i||(i=!0,await s())},0);return()=>{o.off(),c.off(),clearTimeout(a)}}))});return o};var F=()=>Math.floor(Date.now()/1e3);function ye(e){return typeof e=="object"&&e!==null&&"data"in e&&"error"in e?e:{data:e,error:null}}var dt=5;function Oe(e){let{sessionAtom:t,sessionSignal:r,$fetch:n,options:o={}}=e,s=o.sessionOptions?.refetchInterval??0,i=o.sessionOptions?.refetchOnWindowFocus??!0,c=o.sessionOptions?.refetchWhenOffline??!1,a={lastSync:0,lastSessionRequest:0,cachedSession:void 0},u=()=>c||W().isOnline,l=_=>{if(!u())return;if(_?.event==="storage"){a.lastSync=F(),r.set(!r.get());return}let O=t.get(),m=()=>{a.lastSessionRequest=F(),n("/get-session").then(async f=>{let{data:h,error:D}=ye(f);if(h?.needsRefresh)try{let x=await n("/get-session",{method:"POST"});({data:h,error:D}=ye(x))}catch{}let J=h?.session&&h?.user?h:null;t.set({...O,data:J,error:D}),a.lastSync=F(),r.set(!r.get())}).catch(()=>{})};if(_?.event==="poll"){m();return}if(_?.event==="visibilitychange"){if(F()-a.lastSessionRequest<dt)return;a.lastSessionRequest=F()}if(_?.event==="visibilitychange"){m();return}(O?.data===null||O?.data===void 0)&&(a.lastSync=F(),r.set(!r.get()))},d=_=>{q().post({event:"session",data:{trigger:_},clientId:Math.random().toString(36).substring(7)})},p=()=>{s&&s>0&&(a.pollInterval=setInterval(()=>{t.get()?.data&&l({event:"poll"})},s*1e3))},E=()=>{a.unsubscribeBroadcast=q().subscribe(()=>{l({event:"storage"})})},y=()=>{i&&(a.unsubscribeFocus=ee().subscribe(()=>{l({event:"visibilitychange"})}))},N=()=>{a.unsubscribeOnline=W().subscribe(_=>{_&&l({event:"visibilitychange"})})};return{init:()=>{p(),E(),y(),N(),q().setup(),ee().setup(),W().setup()},cleanup:()=>{a.pollInterval&&(clearInterval(a.pollInterval),a.pollInterval=void 0),a.unsubscribeBroadcast&&(a.unsubscribeBroadcast(),a.unsubscribeBroadcast=void 0),a.unsubscribeFocus&&(a.unsubscribeFocus(),a.unsubscribeFocus=void 0),a.unsubscribeOnline&&(a.unsubscribeOnline(),a.unsubscribeOnline=void 0),a.lastSync=0,a.lastSessionRequest=0,a.cachedSession=void 0},triggerRefetch:l,broadcastSessionUpdate:d}}var $=Object.create(null),j=e=>globalThis.process?.env||globalThis.Deno?.env.toObject()||globalThis.__env__||(e?$:globalThis),L=new Proxy($,{get(e,t){return j()[t]??$[t]},has(e,t){return t in j()||t in $},set(e,t,r){let n=j(!0);return n[t]=r,!0},deleteProperty(e,t){if(!t)return!1;let r=j(!0);return delete r[t],!0},ownKeys(){let e=j(!0);return Object.keys(e)}});var pt=typeof process<"u"&&process.env&&process.env.NODE_ENV||"";function P(e,t){return typeof process<"u"&&process.env?process.env[e]??t:typeof Deno<"u"?Deno.env.get(e)??t:typeof Bun<"u"?Bun.env[e]??t:t}var ht=Object.freeze({get BETTER_AUTH_SECRET(){return P("BETTER_AUTH_SECRET")},get AUTH_SECRET(){return P("AUTH_SECRET")},get BETTER_AUTH_TELEMETRY(){return P("BETTER_AUTH_TELEMETRY")},get BETTER_AUTH_TELEMETRY_ID(){return P("BETTER_AUTH_TELEMETRY_ID")},get NODE_ENV(){return P("NODE_ENV","development")},get PACKAGE_VERSION(){return P("PACKAGE_VERSION","0.0.0")},get BETTER_AUTH_TELEMETRY_ENDPOINT(){return P("BETTER_AUTH_TELEMETRY_ENDPOINT","")}});function ge(e){return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,{code:t,message:r,toString:()=>t}]))}function mt(){let e=Object.getOwnPropertyDescriptor(Error,"stackTraceLimit");return e===void 0?Object.isExtensible(Error):Object.prototype.hasOwnProperty.call(e,"writable")?e.writable:e.set!==void 0}function Et(e){let t=e.split(`
2
+ at `);return t.length<=1?e:(t.splice(1,1),t.join(`
3
+ at `))}function _t(e,t){class r extends e{#e;constructor(...o){if(mt()){let i=Error.stackTraceLimit;Error.stackTraceLimit=0,super(...o),Error.stackTraceLimit=i}else super(...o);let s=new Error().stack;s&&(this.#e=Et(s.replace(/^Error/,this.name)))}get errorStack(){return this.#e}}return Object.defineProperty(r.prototype,"constructor",{get(){return t},enumerable:!1,configurable:!0}),r}var Rt={OK:200,CREATED:201,ACCEPTED:202,NO_CONTENT:204,MULTIPLE_CHOICES:300,MOVED_PERMANENTLY:301,FOUND:302,SEE_OTHER:303,NOT_MODIFIED:304,TEMPORARY_REDIRECT:307,BAD_REQUEST:400,UNAUTHORIZED:401,PAYMENT_REQUIRED:402,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,NOT_ACCEPTABLE:406,PROXY_AUTHENTICATION_REQUIRED:407,REQUEST_TIMEOUT:408,CONFLICT:409,GONE:410,LENGTH_REQUIRED:411,PRECONDITION_FAILED:412,PAYLOAD_TOO_LARGE:413,URI_TOO_LONG:414,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,EXPECTATION_FAILED:417,"I'M_A_TEAPOT":418,MISDIRECTED_REQUEST:421,UNPROCESSABLE_ENTITY:422,LOCKED:423,FAILED_DEPENDENCY:424,TOO_EARLY:425,UPGRADE_REQUIRED:426,PRECONDITION_REQUIRED:428,TOO_MANY_REQUESTS:429,REQUEST_HEADER_FIELDS_TOO_LARGE:431,UNAVAILABLE_FOR_LEGAL_REASONS:451,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504,HTTP_VERSION_NOT_SUPPORTED:505,VARIANT_ALSO_NEGOTIATES:506,INSUFFICIENT_STORAGE:507,LOOP_DETECTED:508,NOT_EXTENDED:510,NETWORK_AUTHENTICATION_REQUIRED:511},yt=class extends Error{constructor(e="INTERNAL_SERVER_ERROR",t=void 0,r={},n=typeof e=="number"?e:Rt[e]){super(t?.message,t?.cause?{cause:t.cause}:void 0),this.status=e,this.body=t,this.headers=r,this.statusCode=n,this.name="APIError",this.status=e,this.headers=r,this.statusCode=n,this.body=t}};var Ot=_t(yt,Error);var C=class extends Error{constructor(e,t){super(e,t),this.name="BetterAuthError",this.message=e,this.stack=""}};function gt(e){try{return(new URL(e).pathname.replace(/\/+$/,"")||"/")!=="/"}catch{throw new C(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function Tt(e){try{let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw new C(`Invalid base URL: ${e}. URL must include 'http://' or 'https://'`)}catch(t){throw t instanceof C?t:new C(`Invalid base URL: ${e}. Please provide a valid base URL.`,{cause:t})}}function H(e,t="/api/auth"){if(Tt(e),gt(e))return e;let r=e.replace(/\/+$/,"");return!t||t==="/"?r:(t=t.startsWith("/")?t:`/${t}`,`${r}${t}`)}function Te(e,t){return!e||e.trim()===""?!1:t==="proto"?e==="http"||e==="https":t==="host"?[/\.\./,/\0/,/[\s]/,/^[.]/,/[<>'"]/,/javascript:/i,/file:/i,/data:/i].some(r=>r.test(e))?!1:/^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*(:[0-9]{1,5})?$/.test(e)||/^(\d{1,3}\.){3}\d{1,3}(:[0-9]{1,5})?$/.test(e)||/^\[[0-9a-fA-F:]+\](:[0-9]{1,5})?$/.test(e)||/^localhost(:[0-9]{1,5})?$/i.test(e):!1}function Se(e,t,r,n,o){if(e)return H(e,t);if(n!==!1){let c=L.BETTER_AUTH_URL||L.NEXT_PUBLIC_BETTER_AUTH_URL||L.PUBLIC_BETTER_AUTH_URL||L.NUXT_PUBLIC_BETTER_AUTH_URL||L.NUXT_PUBLIC_AUTH_URL||(L.BASE_URL!=="/"?L.BASE_URL:void 0);if(c)return H(c,t)}let s=r?.headers.get("x-forwarded-host"),i=r?.headers.get("x-forwarded-proto");if(s&&i&&o&&Te(i,"proto")&&Te(s,"host"))try{return H(`${i}://${s}`,t)}catch{}if(r){let c=St(r.url);if(!c)throw new C("Could not get origin from request. Please provide a valid base URL.");return H(c,t)}if(typeof window<"u"&&window.location)return H(window.location.origin,t)}function St(e){try{let t=new URL(e);return t.origin==="null"?null:t.origin}catch{return null}}var ve={id:"redirect",name:"Redirect",hooks:{onSuccess(e){if(e.data?.url&&e.data?.redirect&&typeof window<"u"&&window.location&&window.location)try{window.location.href=e.data.url}catch{}}}};function Ae(e,t){let r=B(!1),n=Re(r,"/get-session",e,{method:"GET"}),o=()=>{};return Y(n,()=>{let s=Oe({sessionAtom:n,sessionSignal:r,$fetch:e,options:t});return s.init(),o=s.broadcastSessionUpdate,()=>{s.cleanup()}}),{session:n,$sessionSignal:r,broadcastSessionUpdate:s=>o(s)}}function re(e){if(e===null||typeof e!="object")return!1;let t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype&&Object.getPrototypeOf(t)!==null||Symbol.iterator in e?!1:Symbol.toStringTag in e?Object.prototype.toString.call(e)==="[object Module]":!0}function ne(e,t,r=".",n){if(!re(t))return ne(e,{},r,n);let o={...t};for(let s of Object.keys(e)){if(s==="__proto__"||s==="constructor")continue;let i=e[s];i!=null&&(n&&n(o,s,i,r)||(Array.isArray(i)&&Array.isArray(o[s])?o[s]=[...i,...o[s]]:re(i)&&re(o[s])?o[s]=ne(i,o[s],(r?`${r}.`:"")+s.toString(),n):o[s]=i))}return o}function oe(e){return(...t)=>t.reduce((r,n)=>ne(r,n,"",e),{})}var be=oe(),zr=oe((e,t,r)=>{if(e[t]!==void 0&&typeof r=="function")return e[t]=r(e[t]),!0}),Jr=oe((e,t,r)=>{if(Array.isArray(e[t])&&typeof r=="function")return e[t]=r(e[t]),!0});var vt=Object.defineProperty,At=Object.defineProperties,bt=Object.getOwnPropertyDescriptors,we=Object.getOwnPropertySymbols,wt=Object.prototype.hasOwnProperty,Ut=Object.prototype.propertyIsEnumerable,Ue=(e,t,r)=>t in e?vt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,A=(e,t)=>{for(var r in t||(t={}))wt.call(t,r)&&Ue(e,r,t[r]);if(we)for(var r of we(t))Ut.call(t,r)&&Ue(e,r,t[r]);return e},b=(e,t)=>At(e,bt(t)),Lt=class extends Error{constructor(e,t,r){super(t||e.toString(),{cause:r}),this.status=e,this.statusText=t,this.error=r,Error.captureStackTrace(this,this.constructor)}},Nt=async(e,t)=>{var r,n,o,s,i,c;let a=t||{},u={onRequest:[t?.onRequest],onResponse:[t?.onResponse],onSuccess:[t?.onSuccess],onError:[t?.onError],onRetry:[t?.onRetry]};if(!t||!t?.plugins)return{url:e,options:a,hooks:u};for(let l of t?.plugins||[]){if(l.init){let d=await((r=l.init)==null?void 0:r.call(l,e.toString(),t));a=d.options||a,e=d.url}u.onRequest.push((n=l.hooks)==null?void 0:n.onRequest),u.onResponse.push((o=l.hooks)==null?void 0:o.onResponse),u.onSuccess.push((s=l.hooks)==null?void 0:s.onSuccess),u.onError.push((i=l.hooks)==null?void 0:i.onError),u.onRetry.push((c=l.hooks)==null?void 0:c.onRetry)}return{url:e,options:a,hooks:u}},Le=class{constructor(e){this.options=e}shouldAttemptRetry(e,t){return this.options.shouldRetry?Promise.resolve(e<this.options.attempts&&this.options.shouldRetry(t)):Promise.resolve(e<this.options.attempts)}getDelay(){return this.options.delay}},It=class{constructor(e){this.options=e}shouldAttemptRetry(e,t){return this.options.shouldRetry?Promise.resolve(e<this.options.attempts&&this.options.shouldRetry(t)):Promise.resolve(e<this.options.attempts)}getDelay(e){return Math.min(this.options.maxDelay,this.options.baseDelay*2**e)}};function Pt(e){if(typeof e=="number")return new Le({type:"linear",attempts:e,delay:1e3});switch(e.type){case"linear":return new Le(e);case"exponential":return new It(e);default:throw new Error("Invalid retry strategy")}}var Ct=async e=>{let t={},r=async n=>typeof n=="function"?await n():n;if(e?.auth){if(e.auth.type==="Bearer"){let n=await r(e.auth.token);if(!n)return t;t.authorization=`Bearer ${n}`}else if(e.auth.type==="Basic"){let[n,o]=await Promise.all([r(e.auth.username),r(e.auth.password)]);if(!n||!o)return t;t.authorization=`Basic ${btoa(`${n}:${o}`)}`}else if(e.auth.type==="Custom"){let[n,o]=await Promise.all([r(e.auth.prefix),r(e.auth.value)]);if(!o)return t;t.authorization=`${n??""} ${o}`}}return t},Dt=/^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;function xt(e){let t=e.headers.get("content-type"),r=new Set(["image/svg","application/xml","application/xhtml","application/html"]);if(!t)return"json";let n=t.split(";").shift()||"";return Dt.test(n)?"json":r.has(n)||n.startsWith("text/")?"text":"blob"}function Mt(e){try{return JSON.parse(e),!0}catch{return!1}}function se(e){if(e===void 0)return!1;let t=typeof e;return t==="string"||t==="number"||t==="boolean"||t===null?!0:t!=="object"?!1:Array.isArray(e)?!0:e.buffer?!1:e.constructor&&e.constructor.name==="Object"||typeof e.toJSON=="function"}function Ne(e){try{return JSON.parse(e)}catch{return e}}function Ie(e){return typeof e=="function"}function Ft(e){if(e?.customFetchImpl)return e.customFetchImpl;if(typeof globalThis<"u"&&Ie(globalThis.fetch))return globalThis.fetch;if(typeof window<"u"&&Ie(window.fetch))return window.fetch;throw new Error("No fetch implementation found")}async function kt(e){let t=new Headers(e?.headers),r=await Ct(e);for(let[n,o]of Object.entries(r||{}))t.set(n,o);if(!t.has("content-type")){let n=Bt(e?.body);n&&t.set("content-type",n)}return t}function Bt(e){return se(e)?"application/json":null}function Yt(e){if(!e?.body)return null;let t=new Headers(e?.headers);if(se(e.body)&&!t.has("content-type")){for(let[r,n]of Object.entries(e?.body))n instanceof Date&&(e.body[r]=n.toISOString());return JSON.stringify(e.body)}return t.has("content-type")&&t.get("content-type")==="application/x-www-form-urlencoded"&&se(e.body)?new URLSearchParams(e.body).toString():e.body}function jt(e,t){var r;if(t?.method)return t.method.toUpperCase();if(e.startsWith("@")){let n=(r=e.split("@")[1])==null?void 0:r.split("/")[0];return Ce.includes(n)?n.toUpperCase():t?.body?"POST":"GET"}return t?.body?"POST":"GET"}function Ht(e,t){let r;return!e?.signal&&e?.timeout&&(r=setTimeout(()=>t?.abort(),e?.timeout)),{abortTimeout:r,clearTimeout:()=>{r&&clearTimeout(r)}}}var qt=class Pe extends Error{constructor(t,r){super(r||JSON.stringify(t,null,2)),this.issues=t,Object.setPrototypeOf(this,Pe.prototype)}};async function z(e,t){let r=await e["~standard"].validate(t);if(r.issues)throw new qt(r.issues);return r.value}var Ce=["get","post","put","patch","delete"];var Wt=e=>({id:"apply-schema",name:"Apply Schema",version:"1.0.0",async init(t,r){var n,o,s,i;let c=((o=(n=e.plugins)==null?void 0:n.find(a=>{var u;return(u=a.schema)!=null&&u.config?t.startsWith(a.schema.config.baseURL||"")||t.startsWith(a.schema.config.prefix||""):!1}))==null?void 0:o.schema)||e.schema;if(c){let a=t;(s=c.config)!=null&&s.prefix&&a.startsWith(c.config.prefix)&&(a=a.replace(c.config.prefix,""),c.config.baseURL&&(t=t.replace(c.config.prefix,c.config.baseURL))),(i=c.config)!=null&&i.baseURL&&a.startsWith(c.config.baseURL)&&(a=a.replace(c.config.baseURL,""));let u=c.schema[a];if(u){let l=b(A({},r),{method:u.method,output:u.output});return r?.disableValidation||(l=b(A({},l),{body:u.input?await z(u.input,r?.body):r?.body,params:u.params?await z(u.params,r?.params):r?.params,query:u.query?await z(u.query,r?.query):r?.query})),{url:t,options:l}}}return{url:t,options:r}}}),De=e=>{async function t(r,n){let o=b(A(A({},e),n),{plugins:[...e?.plugins||[],Wt(e||{}),...n?.plugins||[]]});if(e?.catchAllError)try{return await ie(r,o)}catch(s){return{data:null,error:{status:500,statusText:"Fetch Error",message:"Fetch related error. Captured by catchAllError option. See error property for more details.",error:s}}}return await ie(r,o)}return t};function Vt(e,t){let{baseURL:r,params:n,query:o}=t||{query:{},params:{},baseURL:""},s=e.startsWith("http")?e.split("/").slice(0,3).join("/"):r||"";if(e.startsWith("@")){let d=e.toString().split("@")[1].split("/")[0];Ce.includes(d)&&(e=e.replace(`@${d}/`,"/"))}s.endsWith("/")||(s+="/");let[i,c]=e.replace(s,"").split("?"),a=new URLSearchParams(c);for(let[d,p]of Object.entries(o||{})){if(p==null)continue;let E;if(typeof p=="string")E=p;else if(Array.isArray(p)){for(let y of p)a.append(d,y);continue}else E=JSON.stringify(p);a.set(d,E)}if(n)if(Array.isArray(n)){let d=i.split("/").filter(p=>p.startsWith(":"));for(let[p,E]of d.entries()){let y=n[p];i=i.replace(E,y)}}else for(let[d,p]of Object.entries(n))i=i.replace(`:${d}`,String(p));i=i.split("/").map(encodeURIComponent).join("/"),i.startsWith("/")&&(i=i.slice(1));let u=a.toString();return u=u.length>0?`?${u}`.replace(/\+/g,"%20"):"",s.startsWith("http")?new URL(`${i}${u}`,s):`${s}${i}${u}`}var ie=async(e,t)=>{var r,n,o,s,i,c,a,u;let{hooks:l,url:d,options:p}=await Nt(e,t),E=Ft(p),y=new AbortController,N=(r=p.signal)!=null?r:y.signal,g=Vt(d,p),T=Yt(p),_=await kt(p),O=jt(d,p),m=b(A({},p),{url:g,headers:_,body:T,method:O,signal:N});for(let S of l.onRequest)if(S){let R=await S(m);typeof R=="object"&&R!==null&&(m=R)}("pipeTo"in m&&typeof m.pipeTo=="function"||typeof((n=t?.body)==null?void 0:n.pipe)=="function")&&("duplex"in m||(m.duplex="half"));let{clearTimeout:f}=Ht(p,y),h=await E(m.url,m);f();let D={response:h,request:m};for(let S of l.onResponse)if(S){let R=await S(b(A({},D),{response:(o=t?.hookOptions)!=null&&o.cloneResponse?h.clone():h}));R instanceof Response?h=R:typeof R=="object"&&R!==null&&(h=R.response)}if(h.ok){if(!(m.method!=="HEAD"))return{data:"",error:null};let R=xt(h),w={data:null,response:h,request:m};if(R==="json"||R==="text"){let U=await h.text(),Ve=(s=m.jsonParser)!=null?s:Ne;w.data=await Ve(U)}else w.data=await h[R]();m?.output&&m.output&&!m.disableValidation&&(w.data=await z(m.output,w.data));for(let U of l.onSuccess)U&&await U(b(A({},w),{response:(i=t?.hookOptions)!=null&&i.cloneResponse?h.clone():h}));return t?.throw?w.data:{data:w.data,error:null}}let J=(c=t?.jsonParser)!=null?c:Ne,x=await h.text(),de=Mt(x),Q=de?await J(x):null,We={response:h,responseText:x,request:m,error:b(A({},Q),{status:h.status,statusText:h.statusText})};for(let S of l.onError)S&&await S(b(A({},We),{response:(a=t?.hookOptions)!=null&&a.cloneResponse?h.clone():h}));if(t?.retry){let S=Pt(t.retry),R=(u=t.retryAttempt)!=null?u:0;if(await S.shouldAttemptRetry(R,h)){for(let U of l.onRetry)U&&await U(D);let w=S.getDelay(R);return await new Promise(U=>setTimeout(U,w)),await ie(e,b(A({},t),{retryAttempt:R+1}))}}if(t?.throw)throw new Lt(h.status,h.statusText,de?Q:x);return{data:null,error:b(A({},Q),{status:h.status,statusText:h.statusText})}};var Gt=e=>{if(typeof process>"u")return;let t=e??"/api/auth";if(process.env.NEXT_PUBLIC_AUTH_URL)return process.env.NEXT_PUBLIC_AUTH_URL;if(typeof window>"u"){if(process.env.NEXTAUTH_URL)try{return process.env.NEXTAUTH_URL}catch{}if(process.env.VERCEL_URL)try{let r=process.env.VERCEL_URL.startsWith("http")?"":"https://";return`${new URL(`${r}${process.env.VERCEL_URL}`).origin}${t}`}catch{}}},xe=(e,t)=>{let r="credentials"in Request.prototype,n=Se(e?.baseURL,e?.basePath,void 0,t)??Gt(e?.basePath)??"/api/auth",o=e?.plugins?.flatMap(f=>f.fetchPlugins).filter(f=>f!==void 0)||[],s={id:"lifecycle-hooks",name:"lifecycle-hooks",hooks:{onSuccess:e?.fetchOptions?.onSuccess,onError:e?.fetchOptions?.onError,onRequest:e?.fetchOptions?.onRequest,onResponse:e?.fetchOptions?.onResponse}},{onSuccess:i,onError:c,onRequest:a,onResponse:u,...l}=e?.fetchOptions||{},d=De({baseURL:n,...r?{credentials:"include"}:{},method:"GET",jsonParser(f){return f?Ee(f,{strict:!1}):null},customFetchImpl:fetch,...l,plugins:[s,...l.plugins||[],...e?.disableDefaultFetchPlugins?[]:[ve],...o]}),{$sessionSignal:p,session:E,broadcastSessionUpdate:y}=Ae(d,e),N=e?.plugins||[],g={},T={$sessionSignal:p,session:E},_={"/sign-out":"POST","/revoke-sessions":"POST","/revoke-other-sessions":"POST","/delete-user":"POST"},O=[{signal:"$sessionSignal",matcher(f){return f==="/sign-out"||f==="/update-user"||f==="/update-session"||f==="/sign-up/email"||f==="/sign-in/email"||f==="/delete-user"||f==="/verify-email"||f==="/revoke-sessions"||f==="/revoke-session"||f==="/revoke-other-sessions"||f==="/change-email"||f==="/change-password"},callback(f){f==="/sign-out"?y("signout"):(f==="/update-user"||f==="/update-session")&&y("updateUser")}}];for(let f of N)f.getAtoms&&Object.assign(T,f.getAtoms?.(d)),f.pathMethods&&Object.assign(_,f.pathMethods),f.atomListeners&&O.push(...f.atomListeners);let m={notify:f=>{T[f].set(!T[f].get())},listen:(f,h)=>{T[f].subscribe(h)},atoms:T};for(let f of N)f.getActions&&(g=be(f.getActions?.(d,m,e)??{},g));return{get baseURL(){return n},pluginsActions:g,pluginsAtoms:T,pluginPathMethods:_,atomListeners:O,$fetch:d,$store:m}};function Me(e){return typeof e=="object"&&e!==null&&"get"in e&&typeof e.get=="function"&&"lc"in e&&typeof e.lc=="number"}function $t(e,t,r){let n=t[e],{fetchOptions:o,query:s,...i}=r||{};return n||(o?.method?o.method:i&&Object.keys(i).length>0?"POST":"GET")}function Fe(e,t,r,n,o){function s(i=[]){return new Proxy(function(){},{get(c,a){if(typeof a!="string"||a==="then"||a==="catch"||a==="finally")return;let u=[...i,a],l=e;for(let d of u)if(l&&typeof l=="object"&&d in l)l=l[d];else{l=void 0;break}return typeof l=="function"||Me(l)?l:s(u)},apply:async(c,a,u)=>{let l="/"+i.map(_=>_.replace(/[A-Z]/g,O=>`-${O.toLowerCase()}`)).join("/"),d=u[0]||{},p=u[1]||{},{query:E,fetchOptions:y,...N}=d,g={...p,...y},T=$t(l,r,d);return await t(l,{...g,body:T==="GET"?void 0:{...N,...g?.body||{}},query:E||g?.query,method:T,async onSuccess(_){if(await g?.onSuccess?.(_),!o||g.disableSignal)return;let O=o.filter(f=>f.matcher(l));if(!O.length)return;let m=new Set;for(let f of O){let h=n[f.signal];if(!h)return;if(m.has(f.signal))continue;m.add(f.signal);let D=h.get();setTimeout(()=>{h.set(!D)},10),f.callback?.(l)}}})}})}return s()}function ke(e){return e.charAt(0).toUpperCase()+e.slice(1)}function ae(e){let{pluginPathMethods:t,pluginsActions:r,pluginsAtoms:n,$fetch:o,atomListeners:s,$store:i}=xe(e),c={};for(let[a,u]of Object.entries(n))c[`use${ke(a)}`]=u;return Fe({...r,...c,$fetch:o,$store:i},o,t,n,s)}var Be=ge({FAILED_TO_CREATE_USER:"Failed to create user",USER_ALREADY_EXISTS:"User already exists.",USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL:"User already exists. Use another email.",YOU_CANNOT_BAN_YOURSELF:"You cannot ban yourself",YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE:"You are not allowed to change users role",YOU_ARE_NOT_ALLOWED_TO_CREATE_USERS:"You are not allowed to create users",YOU_ARE_NOT_ALLOWED_TO_LIST_USERS:"You are not allowed to list users",YOU_ARE_NOT_ALLOWED_TO_LIST_USERS_SESSIONS:"You are not allowed to list users sessions",YOU_ARE_NOT_ALLOWED_TO_BAN_USERS:"You are not allowed to ban users",YOU_ARE_NOT_ALLOWED_TO_IMPERSONATE_USERS:"You are not allowed to impersonate users",YOU_ARE_NOT_ALLOWED_TO_REVOKE_USERS_SESSIONS:"You are not allowed to revoke users sessions",YOU_ARE_NOT_ALLOWED_TO_DELETE_USERS:"You are not allowed to delete users",YOU_ARE_NOT_ALLOWED_TO_SET_USERS_PASSWORD:"You are not allowed to set users password",BANNED_USER:"You have been banned from this application",YOU_ARE_NOT_ALLOWED_TO_GET_USER:"You are not allowed to get user",NO_DATA_TO_UPDATE:"No data to update",YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS:"You are not allowed to update users",YOU_CANNOT_REMOVE_YOURSELF:"You cannot remove yourself",YOU_ARE_NOT_ALLOWED_TO_SET_NON_EXISTENT_VALUE:"You are not allowed to set a non-existent role value",YOU_CANNOT_IMPERSONATE_ADMINS:"You cannot impersonate admins",INVALID_ROLE_TYPE:"Invalid role type"});function zt(e){return{authorize(t,r="AND"){let n=!1;for(let[o,s]of Object.entries(t)){let i=e[o];if(!i)return{success:!1,error:`You are not allowed to access resource: ${o}`};if(Array.isArray(s))n=s.every(c=>i.includes(c));else if(typeof s=="object"){let c=s;c.connector==="OR"?n=c.actions.some(a=>i.includes(a)):n=c.actions.every(a=>i.includes(a))}else throw new C("Invalid access control request");if(n&&r==="OR")return{success:n};if(!n&&r==="AND")return{success:!1,error:`unauthorized to access resource "${o}"`}}return n?{success:n}:{success:!1,error:"Not authorized"}},statements:e}}function Ye(e){return{newRole(t){return zt(t)},statements:e}}var Jt={user:["create","list","set-role","ban","impersonate","impersonate-admins","delete","set-password","get","update"],session:["list","revoke","delete"]},je=Ye(Jt),le=je.newRole({user:["create","list","set-role","ban","impersonate","delete","set-password","get","update"],session:["list","revoke","delete"]}),ue=je.newRole({user:[],session:[]}),He={admin:le,user:ue};var qe=e=>{if(e.userId&&e.options?.adminUserIds?.includes(e.userId))return!0;if(!e.permissions)return!1;let t=(e.role||e.options?.defaultRole||"user").split(","),r=e.options?.roles||He;for(let n of t)if(r[n]?.authorize(e.permissions)?.success)return!0;return!1};var ce=e=>{let t={admin:le,user:ue,...e?.roles};return{id:"admin-client",version:he,$InferServerPlugin:{},getActions:()=>({admin:{checkRolePermission:r=>qe({role:r.role,options:{ac:e?.ac,roles:t},permissions:r.permissions})}}),pathMethods:{"/admin/list-users":"GET","/admin/stop-impersonating":"POST"},$ERROR_CODES:Be}};var fe=class{client;constructor(t){this.client=ae({baseURL:t.tenantUrl,plugins:[ce()]})}async signIn(t,r){return await this.client.signIn.email({email:t,password:r})}async signUp(t,r,n){return await this.client.signUp.email({email:t,password:r,name:n})}async signOut(){return await this.client.signOut()}async getSession(){return await this.client.getSession()}async hasRole(t){let r=await this.getSession();if(!r?.data?.user)return!1;let n=r.data.user;return!!(n.role===t||n.roles?.includes(t))}async getRoles(){let t=await this.getSession();if(!t?.data?.user)return[];let r=t.data.user,n=[];return r.role&&n.push(r.role),r.roles&&n.push(...r.roles),[...new Set(n)]}};return Xe(Qt);})();
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{createAuthClient as n}from"better-auth/client";import{adminClient as i}from"better-auth/client/plugins";var r=class{client;constructor(t){this.client=n({baseURL:t.tenantUrl,plugins:[i()]})}async signIn(t,s){return await this.client.signIn.email({email:t,password:s})}async signUp(t,s,e){return await this.client.signUp.email({email:t,password:s,name:e})}async signOut(){return await this.client.signOut()}async getSession(){return await this.client.getSession()}async hasRole(t){let s=await this.getSession();if(!s?.data?.user)return!1;let e=s.data.user;return!!(e.role===t||e.roles?.includes(t))}async getRoles(){let t=await this.getSession();if(!t?.data?.user)return[];let s=t.data.user,e=[];return s.role&&e.push(s.role),s.roles&&e.push(...s.roles),[...new Set(e)]}};export{r as AuthSDK};
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "learn-auth-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Open-source Auth SDK for decentralized tenant backends",
5
+ "license": "MIT",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "type": "module",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup src/index.ts --format esm,iife --dts --clean --minify --global-name AuthSDK",
14
+ "dev": "tsc --watch"
15
+ },
16
+ "dependencies": {
17
+ "better-auth": "^1.5.5"
18
+ },
19
+ "devDependencies": {
20
+ "tsup": "^8.5.1",
21
+ "typescript": "^5.0.0"
22
+ }
23
+ }