@onjunctiondev/auth 0.1.2 → 0.2.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.
package/dist/index.cjs CHANGED
@@ -234,4 +234,3 @@ function createJunctionClient(options) {
234
234
  AuthClient,
235
235
  createJunctionClient
236
236
  });
237
- //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -206,4 +206,3 @@ export {
206
206
  AuthClient,
207
207
  createJunctionClient
208
208
  };
209
- //# sourceMappingURL=index.js.map
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
6
10
  var __copyProps = (to, from, except, desc) => {
7
11
  if (from && typeof from === "object" || typeof from === "function") {
8
12
  for (let key of __getOwnPropNames(from))
@@ -15,8 +19,65 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
15
19
 
16
20
  // src/react/index.ts
17
21
  var react_exports = {};
22
+ __export(react_exports, {
23
+ JunctionProvider: () => JunctionProvider,
24
+ useJunctionAuth: () => useJunctionAuth,
25
+ useJunctionSession: () => useJunctionSession,
26
+ useJunctionUser: () => useJunctionUser
27
+ });
18
28
  module.exports = __toCommonJS(react_exports);
19
- throw new Error(
20
- "@onjunctiondev/auth/react is not available in slice 1. React hooks ship with slice 2. Use the core client via '@onjunctiondev/auth' for now."
21
- );
22
- //# sourceMappingURL=index.cjs.map
29
+ var import_react = require("react");
30
+ var JunctionAuthContext = (0, import_react.createContext)(null);
31
+ function JunctionProvider(props) {
32
+ const { client, children } = props;
33
+ const [state, setState] = (0, import_react.useState)(() => ({
34
+ session: client.auth.getSession().data?.session ?? null,
35
+ isLoading: true
36
+ }));
37
+ (0, import_react.useEffect)(() => {
38
+ const sub = client.auth.onAuthStateChange((_event, session) => {
39
+ setState({ session, isLoading: false });
40
+ });
41
+ return () => sub.unsubscribe();
42
+ }, [client]);
43
+ const value = (0, import_react.useMemo)(() => ({ client, state }), [client, state]);
44
+ return (0, import_react.createElement)(JunctionAuthContext.Provider, { value }, children);
45
+ }
46
+ function useCtx() {
47
+ const ctx = (0, import_react.useContext)(JunctionAuthContext);
48
+ if (!ctx) {
49
+ throw new Error(
50
+ "Junction auth hook called outside <JunctionProvider>. Wrap your app in <JunctionProvider client={...}>."
51
+ );
52
+ }
53
+ return ctx;
54
+ }
55
+ function useJunctionSession() {
56
+ const { state } = useCtx();
57
+ return { session: state.session, isLoading: state.isLoading };
58
+ }
59
+ function useJunctionUser() {
60
+ const { state } = useCtx();
61
+ return { user: state.session?.user ?? null, isLoading: state.isLoading };
62
+ }
63
+ function useJunctionAuth() {
64
+ const { client } = useCtx();
65
+ const signIn = (0, import_react.useCallback)(
66
+ (email, password) => client.auth.signIn({ email, password }),
67
+ [client]
68
+ );
69
+ const signUp = (0, import_react.useCallback)(
70
+ (email, password) => client.auth.signUp({ email, password }),
71
+ [client]
72
+ );
73
+ const signOut = (0, import_react.useCallback)(() => client.auth.signOut(), [client]);
74
+ const refreshSession = (0, import_react.useCallback)(() => client.auth.refreshSession(), [client]);
75
+ return { signIn, signUp, signOut, refreshSession };
76
+ }
77
+ // Annotate the CommonJS export names for ESM import in node:
78
+ 0 && (module.exports = {
79
+ JunctionProvider,
80
+ useJunctionAuth,
81
+ useJunctionSession,
82
+ useJunctionUser
83
+ });
@@ -1,2 +1,32 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { JunctionClient, AuthSession, Result, AuthUser } from '../index.cjs';
1
4
 
2
- export { }
5
+ type SessionState = {
6
+ session: AuthSession | null;
7
+ isLoading: boolean;
8
+ };
9
+ type ContextValue = {
10
+ client: JunctionClient;
11
+ state: SessionState;
12
+ };
13
+ declare function JunctionProvider(props: {
14
+ client: JunctionClient;
15
+ children: ReactNode;
16
+ }): react.FunctionComponentElement<react.ProviderProps<ContextValue | null>>;
17
+ declare function useJunctionSession(): {
18
+ session: AuthSession | null;
19
+ isLoading: boolean;
20
+ };
21
+ declare function useJunctionUser(): {
22
+ user: AuthUser | null;
23
+ isLoading: boolean;
24
+ };
25
+ declare function useJunctionAuth(): {
26
+ signIn: (email: string, password: string) => Promise<Result<AuthSession>>;
27
+ signUp: (email: string, password: string) => Promise<Result<AuthSession>>;
28
+ signOut: () => Promise<Result<null>>;
29
+ refreshSession: () => Promise<Result<AuthSession>>;
30
+ };
31
+
32
+ export { JunctionProvider, useJunctionAuth, useJunctionSession, useJunctionUser };
@@ -1,2 +1,32 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { JunctionClient, AuthSession, Result, AuthUser } from '../index.js';
1
4
 
2
- export { }
5
+ type SessionState = {
6
+ session: AuthSession | null;
7
+ isLoading: boolean;
8
+ };
9
+ type ContextValue = {
10
+ client: JunctionClient;
11
+ state: SessionState;
12
+ };
13
+ declare function JunctionProvider(props: {
14
+ client: JunctionClient;
15
+ children: ReactNode;
16
+ }): react.FunctionComponentElement<react.ProviderProps<ContextValue | null>>;
17
+ declare function useJunctionSession(): {
18
+ session: AuthSession | null;
19
+ isLoading: boolean;
20
+ };
21
+ declare function useJunctionUser(): {
22
+ user: AuthUser | null;
23
+ isLoading: boolean;
24
+ };
25
+ declare function useJunctionAuth(): {
26
+ signIn: (email: string, password: string) => Promise<Result<AuthSession>>;
27
+ signUp: (email: string, password: string) => Promise<Result<AuthSession>>;
28
+ signOut: () => Promise<Result<null>>;
29
+ refreshSession: () => Promise<Result<AuthSession>>;
30
+ };
31
+
32
+ export { JunctionProvider, useJunctionAuth, useJunctionSession, useJunctionUser };
@@ -1,5 +1,63 @@
1
1
  // src/react/index.ts
2
- throw new Error(
3
- "@onjunctiondev/auth/react is not available in slice 1. React hooks ship with slice 2. Use the core client via '@onjunctiondev/auth' for now."
4
- );
5
- //# sourceMappingURL=index.js.map
2
+ import {
3
+ createContext,
4
+ createElement,
5
+ useCallback,
6
+ useContext,
7
+ useEffect,
8
+ useMemo,
9
+ useState
10
+ } from "react";
11
+ var JunctionAuthContext = createContext(null);
12
+ function JunctionProvider(props) {
13
+ const { client, children } = props;
14
+ const [state, setState] = useState(() => ({
15
+ session: client.auth.getSession().data?.session ?? null,
16
+ isLoading: true
17
+ }));
18
+ useEffect(() => {
19
+ const sub = client.auth.onAuthStateChange((_event, session) => {
20
+ setState({ session, isLoading: false });
21
+ });
22
+ return () => sub.unsubscribe();
23
+ }, [client]);
24
+ const value = useMemo(() => ({ client, state }), [client, state]);
25
+ return createElement(JunctionAuthContext.Provider, { value }, children);
26
+ }
27
+ function useCtx() {
28
+ const ctx = useContext(JunctionAuthContext);
29
+ if (!ctx) {
30
+ throw new Error(
31
+ "Junction auth hook called outside <JunctionProvider>. Wrap your app in <JunctionProvider client={...}>."
32
+ );
33
+ }
34
+ return ctx;
35
+ }
36
+ function useJunctionSession() {
37
+ const { state } = useCtx();
38
+ return { session: state.session, isLoading: state.isLoading };
39
+ }
40
+ function useJunctionUser() {
41
+ const { state } = useCtx();
42
+ return { user: state.session?.user ?? null, isLoading: state.isLoading };
43
+ }
44
+ function useJunctionAuth() {
45
+ const { client } = useCtx();
46
+ const signIn = useCallback(
47
+ (email, password) => client.auth.signIn({ email, password }),
48
+ [client]
49
+ );
50
+ const signUp = useCallback(
51
+ (email, password) => client.auth.signUp({ email, password }),
52
+ [client]
53
+ );
54
+ const signOut = useCallback(() => client.auth.signOut(), [client]);
55
+ const refreshSession = useCallback(() => client.auth.refreshSession(), [client]);
56
+ return { signIn, signUp, signOut, refreshSession };
57
+ }
58
+ export {
59
+ JunctionProvider,
60
+ useJunctionAuth,
61
+ useJunctionSession,
62
+ useJunctionUser
63
+ };
@@ -19,4 +19,3 @@ module.exports = __toCommonJS(server_exports);
19
19
  throw new Error(
20
20
  "@onjunctiondev/auth/server is not available in slice 1. Server helpers ship with slice 3."
21
21
  );
22
- //# sourceMappingURL=index.cjs.map
@@ -2,4 +2,3 @@
2
2
  throw new Error(
3
3
  "@onjunctiondev/auth/server is not available in slice 1. Server helpers ship with slice 3."
4
4
  );
5
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onjunctiondev/auth",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Headless auth SDK for Junction — email/password sessions with per-project JWTs and RLS claims.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://onjunction.dev",
@@ -40,9 +40,17 @@
40
40
  "check-types": "tsc --noEmit",
41
41
  "prepublishOnly": "pnpm build"
42
42
  },
43
+ "peerDependencies": {
44
+ "react": "^18.0.0 || ^19.0.0"
45
+ },
46
+ "peerDependenciesMeta": {
47
+ "react": { "optional": true }
48
+ },
43
49
  "devDependencies": {
44
50
  "@junction/typescript-config": "workspace:*",
45
51
  "@types/node": "26.4.1",
52
+ "@types/react": "^19.0.0",
53
+ "react": "^19.0.0",
46
54
  "tsup": "^8.3.5",
47
55
  "typescript": "~5.7.0"
48
56
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/storage.ts","../src/client.ts"],"sourcesContent":["// Entry point for the core SDK — browser, Node, and Edge-compatible.\nimport { AuthClient } from \"./client.js\";\nimport type { ClientOptions } from \"./types.js\";\n\nexport type JunctionClient = {\n auth: AuthClient;\n};\n\nexport function createJunctionClient(options: ClientOptions): JunctionClient {\n return { auth: new AuthClient(options) };\n}\n\nexport type {\n AuthError,\n AuthEvent,\n AuthSession,\n AuthStateChangeHandler,\n AuthUser,\n ClientOptions,\n Result,\n} from \"./types.js\";\nexport { AuthClient } from \"./client.js\";\n","// Pluggable session storage. We pick an adapter at client creation and\n// never touch `window.localStorage` directly from the client itself —\n// that lets the same client run in Node (tests), the browser, and\n// non-DOM runtimes without conditional branches littered through the\n// request path.\nimport type { AuthSession } from \"./types.js\";\n\nexport interface SessionStorage {\n get(): AuthSession | null;\n set(session: AuthSession | null): void;\n}\n\nexport function memoryStorage(): SessionStorage {\n let session: AuthSession | null = null;\n return {\n get: () => session,\n set: (s) => {\n session = s;\n },\n };\n}\n\nexport function localStorageStorage(key: string): SessionStorage {\n const canUse = typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis;\n return {\n get() {\n if (!canUse) return null;\n try {\n const raw = globalThis.localStorage.getItem(key);\n if (!raw) return null;\n return JSON.parse(raw) as AuthSession;\n } catch {\n return null;\n }\n },\n set(session) {\n if (!canUse) return;\n try {\n if (session) {\n globalThis.localStorage.setItem(key, JSON.stringify(session));\n } else {\n globalThis.localStorage.removeItem(key);\n }\n } catch {\n // storage can throw (quota, private mode); ignore silently\n }\n },\n };\n}\n","// Core Junction auth client. Zero UI; typed functions over `fetch` with\n// session caching, auth state subscribers, and an automatic refresh-on-401\n// interceptor. Mirrors the GoTrue surface so consumers can port familiar\n// patterns without translation.\n//\n// Shape of every op: `{ data, error }`. We never throw across the API\n// boundary — a network failure, a bad credential, or a server error all\n// surface as `error.code` strings callers can switch on.\nimport type {\n AuthError,\n AuthEvent,\n AuthSession,\n AuthStateChangeHandler,\n AuthUser,\n ClientOptions,\n Result,\n} from \"./types.js\";\nimport { localStorageStorage, memoryStorage, type SessionStorage } from \"./storage.js\";\n\nconst DEFAULT_STORAGE_KEY = \"junction.auth.session\";\n\ntype RawAuthResponse = {\n status?: AuthSession[\"status\"];\n access_token: string;\n refresh_token: string;\n token_type: \"bearer\";\n expires_in: number;\n expires_at: number;\n user: AuthUser;\n};\n\nfunction pickStorage(opts: ClientOptions): SessionStorage {\n const key = opts.storageKey ?? DEFAULT_STORAGE_KEY;\n if (opts.storage === \"memory\") return memoryStorage();\n // Default: localStorage in the browser, memory elsewhere.\n if (typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis) {\n return localStorageStorage(key);\n }\n return memoryStorage();\n}\n\ntype Deps = {\n url: string;\n fetchFn: typeof fetch;\n storage: SessionStorage;\n};\n\nexport class AuthClient {\n readonly #deps: Deps;\n readonly #listeners = new Set<AuthStateChangeHandler>();\n // Refresh in-flight — concurrent 401s share one refresh so we don't\n // race-rotate the single-use token on the server.\n #inflightRefresh: Promise<Result<AuthSession>> | null = null;\n\n constructor(opts: ClientOptions) {\n this.#deps = {\n url: opts.url.replace(/\\/+$/, \"\"),\n fetchFn: opts.fetch ?? ((...args) => fetch(...args)),\n storage: pickStorage(opts),\n };\n }\n\n // --- public API --------------------------------------------------------\n\n async signUp(credentials: {\n email: string;\n password: string;\n }): Promise<Result<AuthSession>> {\n return this.#authCall(\"/auth/v1/signup\", credentials, \"SIGNED_IN\");\n }\n\n async signIn(credentials: {\n email: string;\n password: string;\n }): Promise<Result<AuthSession>> {\n return this.#authCall(\n \"/auth/v1/token?grant_type=password\",\n credentials,\n \"SIGNED_IN\",\n );\n }\n\n async signOut(): Promise<Result<null>> {\n const session = this.#deps.storage.get();\n this.#deps.storage.set(null);\n this.#emit(\"SIGNED_OUT\", null);\n if (!session) return { data: null, error: null };\n const res = await this.#rawFetch(\"/auth/v1/logout\", {\n method: \"POST\",\n headers: { authorization: `Bearer ${session.access_token}` },\n }).catch(() => null);\n if (!res) {\n // Signed out locally regardless of upstream reachability — the UX\n // is a sign-out, not \"sign out iff the network cooperates\".\n return { data: null, error: null };\n }\n if (!res.ok && res.status !== 401) {\n return { data: null, error: await parseError(res) };\n }\n return { data: null, error: null };\n }\n\n async refreshSession(): Promise<Result<AuthSession>> {\n if (this.#inflightRefresh) return this.#inflightRefresh;\n const session = this.#deps.storage.get();\n if (!session) {\n return { data: null, error: errorFrom(\"no_session\", \"no session to refresh\", 400) };\n }\n this.#inflightRefresh = this.#authCall(\n \"/auth/v1/token?grant_type=refresh_token\",\n { refresh_token: session.refresh_token },\n \"TOKEN_REFRESHED\",\n ).finally(() => {\n this.#inflightRefresh = null;\n });\n return this.#inflightRefresh;\n }\n\n getSession(): Result<{ session: AuthSession | null }> {\n return { data: { session: this.#deps.storage.get() }, error: null };\n }\n\n async getUser(): Promise<Result<{ user: AuthUser | null }>> {\n const session = this.#deps.storage.get();\n if (!session) return { data: { user: null }, error: null };\n const res = await this.#authedFetch(\"/auth/v1/user\", { method: \"GET\" });\n if (res.error) return { data: null, error: res.error };\n return { data: { user: res.data as AuthUser }, error: null };\n }\n\n onAuthStateChange(handler: AuthStateChangeHandler): { unsubscribe: () => void } {\n this.#listeners.add(handler);\n // Fire initial state synchronously so subscribers get the current\n // session without an extra tick.\n try {\n const session = this.#deps.storage.get();\n handler(session ? \"SIGNED_IN\" : \"SIGNED_OUT\", session);\n } catch {\n // ignore subscriber errors\n }\n return {\n unsubscribe: () => {\n this.#listeners.delete(handler);\n },\n };\n }\n\n // --- internals ---------------------------------------------------------\n\n async #authCall(\n path: string,\n body: unknown,\n event: AuthEvent,\n ): Promise<Result<AuthSession>> {\n const res = await this.#rawFetch(path, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n }).catch(() => null);\n if (!res) {\n return { data: null, error: errorFrom(\"network_error\", \"network error\", 0) };\n }\n if (!res.ok) return { data: null, error: await parseError(res) };\n const raw = (await res.json()) as RawAuthResponse;\n const session: AuthSession = {\n status: raw.status ?? \"complete\",\n access_token: raw.access_token,\n refresh_token: raw.refresh_token,\n token_type: raw.token_type,\n expires_in: raw.expires_in,\n expires_at: raw.expires_at,\n user: raw.user,\n };\n this.#deps.storage.set(session);\n this.#emit(event, session);\n return { data: session, error: null };\n }\n\n // Fetches a protected endpoint, auto-refreshing once on 401. We don't\n // loop — a second 401 after a successful refresh means the user is\n // genuinely signed out, propagate as such.\n async #authedFetch(path: string, init: RequestInit): Promise<Result<unknown>> {\n const session = this.#deps.storage.get();\n if (!session) return { data: null, error: errorFrom(\"no_session\", \"no session\", 401) };\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${session.access_token}`);\n let res = await this.#rawFetch(path, { ...init, headers });\n if (res.status === 401) {\n const refreshed = await this.refreshSession();\n if (refreshed.error) {\n this.#deps.storage.set(null);\n this.#emit(\"SIGNED_OUT\", null);\n return { data: null, error: refreshed.error };\n }\n headers.set(\"authorization\", `Bearer ${refreshed.data.access_token}`);\n res = await this.#rawFetch(path, { ...init, headers });\n }\n if (!res.ok) return { data: null, error: await parseError(res) };\n const body = res.status === 204 ? null : await res.json().catch(() => null);\n return { data: body, error: null };\n }\n\n async #rawFetch(path: string, init: RequestInit): Promise<Response> {\n return this.#deps.fetchFn(`${this.#deps.url}${path}`, init);\n }\n\n #emit(event: AuthEvent, session: AuthSession | null): void {\n for (const l of this.#listeners) {\n try {\n l(event, session);\n } catch {\n // isolate subscribers from each other\n }\n }\n }\n}\n\nfunction errorFrom(code: string, message: string, status: number): AuthError {\n return { code, message, status };\n}\n\nasync function parseError(res: Response): Promise<AuthError> {\n try {\n const body = (await res.json()) as { error?: { message?: string; code?: string } };\n const message = body?.error?.message ?? res.statusText ?? \"request failed\";\n const code = body?.error?.code ?? \"error\";\n return { code, message, status: res.status };\n } catch {\n return { code: \"error\", message: res.statusText || \"request failed\", status: res.status };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,SAAS,gBAAgC;AAC9C,MAAI,UAA8B;AAClC,SAAO;AAAA,IACL,KAAK,MAAM;AAAA,IACX,KAAK,CAAC,MAAM;AACV,gBAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEO,SAAS,oBAAoB,KAA6B;AAC/D,QAAM,SAAS,OAAO,eAAe,eAAe,kBAAkB;AACtE,SAAO;AAAA,IACL,MAAM;AACJ,UAAI,CAAC,OAAQ,QAAO;AACpB,UAAI;AACF,cAAM,MAAM,WAAW,aAAa,QAAQ,GAAG;AAC/C,YAAI,CAAC,IAAK,QAAO;AACjB,eAAO,KAAK,MAAM,GAAG;AAAA,MACvB,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,IAAI,SAAS;AACX,UAAI,CAAC,OAAQ;AACb,UAAI;AACF,YAAI,SAAS;AACX,qBAAW,aAAa,QAAQ,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,QAC9D,OAAO;AACL,qBAAW,aAAa,WAAW,GAAG;AAAA,QACxC;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;;;AC7BA,IAAM,sBAAsB;AAY5B,SAAS,YAAY,MAAqC;AACxD,QAAM,MAAM,KAAK,cAAc;AAC/B,MAAI,KAAK,YAAY,SAAU,QAAO,cAAc;AAEpD,MAAI,OAAO,eAAe,eAAe,kBAAkB,YAAY;AACrE,WAAO,oBAAoB,GAAG;AAAA,EAChC;AACA,SAAO,cAAc;AACvB;AAQO,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA,aAAa,oBAAI,IAA4B;AAAA;AAAA;AAAA,EAGtD,mBAAwD;AAAA,EAExD,YAAY,MAAqB;AAC/B,SAAK,QAAQ;AAAA,MACX,KAAK,KAAK,IAAI,QAAQ,QAAQ,EAAE;AAAA,MAChC,SAAS,KAAK,UAAU,IAAI,SAAS,MAAM,GAAG,IAAI;AAAA,MAClD,SAAS,YAAY,IAAI;AAAA,IAC3B;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,OAAO,aAGoB;AAC/B,WAAO,KAAK,UAAU,mBAAmB,aAAa,WAAW;AAAA,EACnE;AAAA,EAEA,MAAM,OAAO,aAGoB;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,UAAiC;AACrC,UAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,SAAK,MAAM,QAAQ,IAAI,IAAI;AAC3B,SAAK,MAAM,cAAc,IAAI;AAC7B,QAAI,CAAC,QAAS,QAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAC/C,UAAM,MAAM,MAAM,KAAK,UAAU,mBAAmB;AAAA,MAClD,QAAQ;AAAA,MACR,SAAS,EAAE,eAAe,UAAU,QAAQ,YAAY,GAAG;AAAA,IAC7D,CAAC,EAAE,MAAM,MAAM,IAAI;AACnB,QAAI,CAAC,KAAK;AAGR,aAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,IACnC;AACA,QAAI,CAAC,IAAI,MAAM,IAAI,WAAW,KAAK;AACjC,aAAO,EAAE,MAAM,MAAM,OAAO,MAAM,WAAW,GAAG,EAAE;AAAA,IACpD;AACA,WAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,iBAA+C;AACnD,QAAI,KAAK,iBAAkB,QAAO,KAAK;AACvC,UAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,QAAI,CAAC,SAAS;AACZ,aAAO,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,yBAAyB,GAAG,EAAE;AAAA,IACpF;AACA,SAAK,mBAAmB,KAAK;AAAA,MAC3B;AAAA,MACA,EAAE,eAAe,QAAQ,cAAc;AAAA,MACvC;AAAA,IACF,EAAE,QAAQ,MAAM;AACd,WAAK,mBAAmB;AAAA,IAC1B,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAsD;AACpD,WAAO,EAAE,MAAM,EAAE,SAAS,KAAK,MAAM,QAAQ,IAAI,EAAE,GAAG,OAAO,KAAK;AAAA,EACpE;AAAA,EAEA,MAAM,UAAsD;AAC1D,UAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,QAAI,CAAC,QAAS,QAAO,EAAE,MAAM,EAAE,MAAM,KAAK,GAAG,OAAO,KAAK;AACzD,UAAM,MAAM,MAAM,KAAK,aAAa,iBAAiB,EAAE,QAAQ,MAAM,CAAC;AACtE,QAAI,IAAI,MAAO,QAAO,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM;AACrD,WAAO,EAAE,MAAM,EAAE,MAAM,IAAI,KAAiB,GAAG,OAAO,KAAK;AAAA,EAC7D;AAAA,EAEA,kBAAkB,SAA8D;AAC9E,SAAK,WAAW,IAAI,OAAO;AAG3B,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,cAAQ,UAAU,cAAc,cAAc,OAAO;AAAA,IACvD,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,MACL,aAAa,MAAM;AACjB,aAAK,WAAW,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,UACJ,MACA,MACA,OAC8B;AAC9B,UAAM,MAAM,MAAM,KAAK,UAAU,MAAM;AAAA,MACrC,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC,EAAE,MAAM,MAAM,IAAI;AACnB,QAAI,CAAC,KAAK;AACR,aAAO,EAAE,MAAM,MAAM,OAAO,UAAU,iBAAiB,iBAAiB,CAAC,EAAE;AAAA,IAC7E;AACA,QAAI,CAAC,IAAI,GAAI,QAAO,EAAE,MAAM,MAAM,OAAO,MAAM,WAAW,GAAG,EAAE;AAC/D,UAAM,MAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,UAAuB;AAAA,MAC3B,QAAQ,IAAI,UAAU;AAAA,MACtB,cAAc,IAAI;AAAA,MAClB,eAAe,IAAI;AAAA,MACnB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,MAAM,IAAI;AAAA,IACZ;AACA,SAAK,MAAM,QAAQ,IAAI,OAAO;AAC9B,SAAK,MAAM,OAAO,OAAO;AACzB,WAAO,EAAE,MAAM,SAAS,OAAO,KAAK;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAAa,MAAc,MAA6C;AAC5E,UAAM,UAAU,KAAK,MAAM,QAAQ,IAAI;AACvC,QAAI,CAAC,QAAS,QAAO,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,cAAc,GAAG,EAAE;AACrF,UAAM,UAAU,IAAI,QAAQ,KAAK,OAAO;AACxC,YAAQ,IAAI,iBAAiB,UAAU,QAAQ,YAAY,EAAE;AAC7D,QAAI,MAAM,MAAM,KAAK,UAAU,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC;AACzD,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,YAAY,MAAM,KAAK,eAAe;AAC5C,UAAI,UAAU,OAAO;AACnB,aAAK,MAAM,QAAQ,IAAI,IAAI;AAC3B,aAAK,MAAM,cAAc,IAAI;AAC7B,eAAO,EAAE,MAAM,MAAM,OAAO,UAAU,MAAM;AAAA,MAC9C;AACA,cAAQ,IAAI,iBAAiB,UAAU,UAAU,KAAK,YAAY,EAAE;AACpE,YAAM,MAAM,KAAK,UAAU,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC;AAAA,IACvD;AACA,QAAI,CAAC,IAAI,GAAI,QAAO,EAAE,MAAM,MAAM,OAAO,MAAM,WAAW,GAAG,EAAE;AAC/D,UAAM,OAAO,IAAI,WAAW,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI;AAC1E,WAAO,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,EACnC;AAAA,EAEA,MAAM,UAAU,MAAc,MAAsC;AAClE,WAAO,KAAK,MAAM,QAAQ,GAAG,KAAK,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI;AAAA,EAC5D;AAAA,EAEA,MAAM,OAAkB,SAAmC;AACzD,eAAW,KAAK,KAAK,YAAY;AAC/B,UAAI;AACF,UAAE,OAAO,OAAO;AAAA,MAClB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,UAAU,MAAc,SAAiB,QAA2B;AAC3E,SAAO,EAAE,MAAM,SAAS,OAAO;AACjC;AAEA,eAAe,WAAW,KAAmC;AAC3D,MAAI;AACF,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,UAAM,UAAU,MAAM,OAAO,WAAW,IAAI,cAAc;AAC1D,UAAM,OAAO,MAAM,OAAO,QAAQ;AAClC,WAAO,EAAE,MAAM,SAAS,QAAQ,IAAI,OAAO;AAAA,EAC7C,QAAQ;AACN,WAAO,EAAE,MAAM,SAAS,SAAS,IAAI,cAAc,kBAAkB,QAAQ,IAAI,OAAO;AAAA,EAC1F;AACF;;;AF9NO,SAAS,qBAAqB,SAAwC;AAC3E,SAAO,EAAE,MAAM,IAAI,WAAW,OAAO,EAAE;AACzC;","names":[]}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/storage.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["// Pluggable session storage. We pick an adapter at client creation and\n// never touch `window.localStorage` directly from the client itself —\n// that lets the same client run in Node (tests), the browser, and\n// non-DOM runtimes without conditional branches littered through the\n// request path.\nimport type { AuthSession } from \"./types.js\";\n\nexport interface SessionStorage {\n get(): AuthSession | null;\n set(session: AuthSession | null): void;\n}\n\nexport function memoryStorage(): SessionStorage {\n let session: AuthSession | null = null;\n return {\n get: () => session,\n set: (s) => {\n session = s;\n },\n };\n}\n\nexport function localStorageStorage(key: string): SessionStorage {\n const canUse = typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis;\n return {\n get() {\n if (!canUse) return null;\n try {\n const raw = globalThis.localStorage.getItem(key);\n if (!raw) return null;\n return JSON.parse(raw) as AuthSession;\n } catch {\n return null;\n }\n },\n set(session) {\n if (!canUse) return;\n try {\n if (session) {\n globalThis.localStorage.setItem(key, JSON.stringify(session));\n } else {\n globalThis.localStorage.removeItem(key);\n }\n } catch {\n // storage can throw (quota, private mode); ignore silently\n }\n },\n };\n}\n","// Core Junction auth client. Zero UI; typed functions over `fetch` with\n// session caching, auth state subscribers, and an automatic refresh-on-401\n// interceptor. Mirrors the GoTrue surface so consumers can port familiar\n// patterns without translation.\n//\n// Shape of every op: `{ data, error }`. We never throw across the API\n// boundary — a network failure, a bad credential, or a server error all\n// surface as `error.code` strings callers can switch on.\nimport type {\n AuthError,\n AuthEvent,\n AuthSession,\n AuthStateChangeHandler,\n AuthUser,\n ClientOptions,\n Result,\n} from \"./types.js\";\nimport { localStorageStorage, memoryStorage, type SessionStorage } from \"./storage.js\";\n\nconst DEFAULT_STORAGE_KEY = \"junction.auth.session\";\n\ntype RawAuthResponse = {\n status?: AuthSession[\"status\"];\n access_token: string;\n refresh_token: string;\n token_type: \"bearer\";\n expires_in: number;\n expires_at: number;\n user: AuthUser;\n};\n\nfunction pickStorage(opts: ClientOptions): SessionStorage {\n const key = opts.storageKey ?? DEFAULT_STORAGE_KEY;\n if (opts.storage === \"memory\") return memoryStorage();\n // Default: localStorage in the browser, memory elsewhere.\n if (typeof globalThis !== \"undefined\" && \"localStorage\" in globalThis) {\n return localStorageStorage(key);\n }\n return memoryStorage();\n}\n\ntype Deps = {\n url: string;\n fetchFn: typeof fetch;\n storage: SessionStorage;\n};\n\nexport class AuthClient {\n readonly #deps: Deps;\n readonly #listeners = new Set<AuthStateChangeHandler>();\n // Refresh in-flight — concurrent 401s share one refresh so we don't\n // race-rotate the single-use token on the server.\n #inflightRefresh: Promise<Result<AuthSession>> | null = null;\n\n constructor(opts: ClientOptions) {\n this.#deps = {\n url: opts.url.replace(/\\/+$/, \"\"),\n fetchFn: opts.fetch ?? ((...args) => fetch(...args)),\n storage: pickStorage(opts),\n };\n }\n\n // --- public API --------------------------------------------------------\n\n async signUp(credentials: {\n email: string;\n password: string;\n }): Promise<Result<AuthSession>> {\n return this.#authCall(\"/auth/v1/signup\", credentials, \"SIGNED_IN\");\n }\n\n async signIn(credentials: {\n email: string;\n password: string;\n }): Promise<Result<AuthSession>> {\n return this.#authCall(\n \"/auth/v1/token?grant_type=password\",\n credentials,\n \"SIGNED_IN\",\n );\n }\n\n async signOut(): Promise<Result<null>> {\n const session = this.#deps.storage.get();\n this.#deps.storage.set(null);\n this.#emit(\"SIGNED_OUT\", null);\n if (!session) return { data: null, error: null };\n const res = await this.#rawFetch(\"/auth/v1/logout\", {\n method: \"POST\",\n headers: { authorization: `Bearer ${session.access_token}` },\n }).catch(() => null);\n if (!res) {\n // Signed out locally regardless of upstream reachability — the UX\n // is a sign-out, not \"sign out iff the network cooperates\".\n return { data: null, error: null };\n }\n if (!res.ok && res.status !== 401) {\n return { data: null, error: await parseError(res) };\n }\n return { data: null, error: null };\n }\n\n async refreshSession(): Promise<Result<AuthSession>> {\n if (this.#inflightRefresh) return this.#inflightRefresh;\n const session = this.#deps.storage.get();\n if (!session) {\n return { data: null, error: errorFrom(\"no_session\", \"no session to refresh\", 400) };\n }\n this.#inflightRefresh = this.#authCall(\n \"/auth/v1/token?grant_type=refresh_token\",\n { refresh_token: session.refresh_token },\n \"TOKEN_REFRESHED\",\n ).finally(() => {\n this.#inflightRefresh = null;\n });\n return this.#inflightRefresh;\n }\n\n getSession(): Result<{ session: AuthSession | null }> {\n return { data: { session: this.#deps.storage.get() }, error: null };\n }\n\n async getUser(): Promise<Result<{ user: AuthUser | null }>> {\n const session = this.#deps.storage.get();\n if (!session) return { data: { user: null }, error: null };\n const res = await this.#authedFetch(\"/auth/v1/user\", { method: \"GET\" });\n if (res.error) return { data: null, error: res.error };\n return { data: { user: res.data as AuthUser }, error: null };\n }\n\n onAuthStateChange(handler: AuthStateChangeHandler): { unsubscribe: () => void } {\n this.#listeners.add(handler);\n // Fire initial state synchronously so subscribers get the current\n // session without an extra tick.\n try {\n const session = this.#deps.storage.get();\n handler(session ? \"SIGNED_IN\" : \"SIGNED_OUT\", session);\n } catch {\n // ignore subscriber errors\n }\n return {\n unsubscribe: () => {\n this.#listeners.delete(handler);\n },\n };\n }\n\n // --- internals ---------------------------------------------------------\n\n async #authCall(\n path: string,\n body: unknown,\n event: AuthEvent,\n ): Promise<Result<AuthSession>> {\n const res = await this.#rawFetch(path, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n }).catch(() => null);\n if (!res) {\n return { data: null, error: errorFrom(\"network_error\", \"network error\", 0) };\n }\n if (!res.ok) return { data: null, error: await parseError(res) };\n const raw = (await res.json()) as RawAuthResponse;\n const session: AuthSession = {\n status: raw.status ?? \"complete\",\n access_token: raw.access_token,\n refresh_token: raw.refresh_token,\n token_type: raw.token_type,\n expires_in: raw.expires_in,\n expires_at: raw.expires_at,\n user: raw.user,\n };\n this.#deps.storage.set(session);\n this.#emit(event, session);\n return { data: session, error: null };\n }\n\n // Fetches a protected endpoint, auto-refreshing once on 401. We don't\n // loop — a second 401 after a successful refresh means the user is\n // genuinely signed out, propagate as such.\n async #authedFetch(path: string, init: RequestInit): Promise<Result<unknown>> {\n const session = this.#deps.storage.get();\n if (!session) return { data: null, error: errorFrom(\"no_session\", \"no session\", 401) };\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${session.access_token}`);\n let res = await this.#rawFetch(path, { ...init, headers });\n if (res.status === 401) {\n const refreshed = await this.refreshSession();\n if (refreshed.error) {\n this.#deps.storage.set(null);\n this.#emit(\"SIGNED_OUT\", null);\n return { data: null, error: refreshed.error };\n }\n headers.set(\"authorization\", `Bearer ${refreshed.data.access_token}`);\n res = await this.#rawFetch(path, { ...init, headers });\n }\n if (!res.ok) return { data: null, error: await parseError(res) };\n const body = res.status === 204 ? null : await res.json().catch(() => null);\n return { data: body, error: null };\n }\n\n async #rawFetch(path: string, init: RequestInit): Promise<Response> {\n return this.#deps.fetchFn(`${this.#deps.url}${path}`, init);\n }\n\n #emit(event: AuthEvent, session: AuthSession | null): void {\n for (const l of this.#listeners) {\n try {\n l(event, session);\n } catch {\n // isolate subscribers from each other\n }\n }\n }\n}\n\nfunction errorFrom(code: string, message: string, status: number): AuthError {\n return { code, message, status };\n}\n\nasync function parseError(res: Response): Promise<AuthError> {\n try {\n const body = (await res.json()) as { error?: { message?: string; code?: string } };\n const message = body?.error?.message ?? res.statusText ?? \"request failed\";\n const code = body?.error?.code ?? \"error\";\n return { code, message, status: res.status };\n } catch {\n return { code: \"error\", message: res.statusText || \"request failed\", status: res.status };\n }\n}\n","// Entry point for the core SDK — browser, Node, and Edge-compatible.\nimport { AuthClient } from \"./client.js\";\nimport type { ClientOptions } from \"./types.js\";\n\nexport type JunctionClient = {\n auth: AuthClient;\n};\n\nexport function createJunctionClient(options: ClientOptions): JunctionClient {\n return { auth: new AuthClient(options) };\n}\n\nexport type {\n AuthError,\n AuthEvent,\n AuthSession,\n AuthStateChangeHandler,\n AuthUser,\n ClientOptions,\n Result,\n} from \"./types.js\";\nexport { AuthClient } from \"./client.js\";\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/react/index.ts"],"sourcesContent":["// React hooks placeholder — scheduled for slice 2. Importing this\n// subpath today throws a clear, actionable error instead of a\n// cryptic missing-export.\nthrow new Error(\n \"@onjunctiondev/auth/react is not available in slice 1. React hooks ship with slice 2. Use the core client via '@onjunctiondev/auth' for now.\",\n);\nexport {};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;AAGA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/react/index.ts"],"sourcesContent":["// React hooks placeholder — scheduled for slice 2. Importing this\n// subpath today throws a clear, actionable error instead of a\n// cryptic missing-export.\nthrow new Error(\n \"@onjunctiondev/auth/react is not available in slice 1. React hooks ship with slice 2. Use the core client via '@onjunctiondev/auth' for now.\",\n);\nexport {};\n"],"mappings":";AAGA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/server/index.ts"],"sourcesContent":["// Next.js server helpers placeholder — scheduled for slice 3. Importing\n// this subpath today throws a clear, actionable error.\nthrow new Error(\n \"@onjunctiondev/auth/server is not available in slice 1. Server helpers ship with slice 3.\",\n);\nexport {};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;AAEA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/server/index.ts"],"sourcesContent":["// Next.js server helpers placeholder — scheduled for slice 3. Importing\n// this subpath today throws a clear, actionable error.\nthrow new Error(\n \"@onjunctiondev/auth/server is not available in slice 1. Server helpers ship with slice 3.\",\n);\nexport {};\n"],"mappings":";AAEA,MAAM,IAAI;AAAA,EACR;AACF;","names":[]}