@obul.ai/sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @obul.ai/sdk
|
|
2
|
+
|
|
3
|
+
Single-package Obul BFF SDK facade with browser client, server core, and framework adapters.
|
|
4
|
+
|
|
5
|
+
## What is a BFF?
|
|
6
|
+
BFF stands for **Backend For Frontend**. It's a small server that sits between your browser app and Obul's APIs. The browser only talks to your BFF, and the BFF handles OAuth, token storage, session cookies, and proxying API calls. This keeps secrets and tokens off the client and lets you enforce auth, rate limits, and request policies in one place.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
```bash
|
|
10
|
+
npm install @obul.ai/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Browser via CDN
|
|
14
|
+
Module (recommended):
|
|
15
|
+
```html
|
|
16
|
+
<script type="module">
|
|
17
|
+
import { createObulClient } from "https://cdn.obul.ai/sdk/v0.1.1/obul-sdk.min.mjs"
|
|
18
|
+
|
|
19
|
+
const obul = createObulClient({ baseUrl: "" })
|
|
20
|
+
obul.signIn()
|
|
21
|
+
</script>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Script tag (global `ObulSDK`):
|
|
25
|
+
```html
|
|
26
|
+
<script src="https://cdn.obul.ai/sdk/v0.1.1/obul-sdk.min.js"></script>
|
|
27
|
+
<script>
|
|
28
|
+
const obul = ObulSDK.createObulClient({ baseUrl: "" })
|
|
29
|
+
obul.signIn()
|
|
30
|
+
</script>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Exports
|
|
34
|
+
- `@obul.ai/sdk/browser` (browser client)
|
|
35
|
+
- `@obul.ai/sdk/server` (server core)
|
|
36
|
+
- `@obul.ai/sdk/adapters/express`
|
|
37
|
+
- `@obul.ai/sdk/adapters/next`
|
|
38
|
+
- `@obul.ai/sdk/adapters/hono`
|
|
39
|
+
- `@obul.ai/sdk/adapters/cloudflare`
|
|
40
|
+
|
|
41
|
+
## Example integrations
|
|
42
|
+
|
|
43
|
+
### Express (BFF server)
|
|
44
|
+
```js
|
|
45
|
+
import express from "express"
|
|
46
|
+
import { createObulExpressRouter } from "@obul.ai/sdk/adapters/express"
|
|
47
|
+
|
|
48
|
+
const app = express()
|
|
49
|
+
const router = createObulExpressRouter({
|
|
50
|
+
issuerUrl: process.env.OBUL_ISSUER_URL,
|
|
51
|
+
authEndpoint: process.env.OBUL_AUTH_ENDPOINT,
|
|
52
|
+
tokenEndpoint: process.env.OBUL_TOKEN_ENDPOINT,
|
|
53
|
+
revocationEndpoint: process.env.OBUL_REVOCATION_ENDPOINT,
|
|
54
|
+
apiBaseUrl: process.env.OBUL_API_BASE_URL,
|
|
55
|
+
clientId: process.env.OBUL_CLIENT_ID,
|
|
56
|
+
clientSecret: process.env.OBUL_CLIENT_SECRET,
|
|
57
|
+
redirectUri: process.env.OBUL_REDIRECT_URI,
|
|
58
|
+
scopes: (process.env.OBUL_SCOPES ?? "openid profile email").split(" ")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
app.use(router)
|
|
62
|
+
app.listen(3000)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### React / Vite (browser client)
|
|
66
|
+
```ts
|
|
67
|
+
import { createObulClient } from "@obul.ai/sdk/browser"
|
|
68
|
+
|
|
69
|
+
const obul = createObulClient({
|
|
70
|
+
baseUrl: "", // BFF origin, if different from the browser origin
|
|
71
|
+
postLoginRedirect: window.location.href,
|
|
72
|
+
postLogoutRedirect: "/",
|
|
73
|
+
sessionCheckIntervalMs: 10_000
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// Example: trigger login
|
|
77
|
+
obul.signIn()
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Next.js (App Router, client component)
|
|
81
|
+
```tsx
|
|
82
|
+
"use client"
|
|
83
|
+
|
|
84
|
+
import { useEffect, useMemo } from "react"
|
|
85
|
+
import { createObulClient } from "@obul.ai/sdk/browser"
|
|
86
|
+
|
|
87
|
+
export function ObulLoginButton() {
|
|
88
|
+
const obul = useMemo(() => createObulClient({ baseUrl: "" }), [])
|
|
89
|
+
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
obul.getSession().catch(() => {})
|
|
92
|
+
}, [obul])
|
|
93
|
+
|
|
94
|
+
return <button onClick={() => obul.signIn()}>Sign in</button>
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Repo
|
|
99
|
+
See the repo for the Express example and additional docs.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var ObulSDK=(()=>{var f=Object.defineProperty;var R=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var C=(s,o)=>{for(var r in o)f(s,r,{get:o[r],enumerable:!0})},S=(s,o,r,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let a of k(o))!v.call(s,a)&&a!==r&&f(s,a,{get:()=>o[a],enumerable:!(i=R(o,a))||i.enumerable});return s};var P=s=>S(f({},"__esModule",{value:!0}),s);var j={};C(j,{createObulClient:()=>_});var b=class{constructor(){this.listeners=new Map}on(o,r){let i=this.listeners.get(o)??new Set;i.add(r),this.listeners.set(o,i)}off(o,r){let i=this.listeners.get(o);i&&i.delete(r)}emit(o,r){let i=this.listeners.get(o);if(i)for(let a of i)a(r)}};function q(s){return s?s.endsWith("/")?s.slice(0,-1):s:""}function E(s){if(typeof document>"u")return;let o=document.cookie.split(";");for(let r of o){let[i,...a]=r.trim().split("=");if(i===s)return decodeURIComponent(a.join("="))}}function T(s){if(!s)return"";let o=new URLSearchParams;for(let[i,a]of Object.entries(s))o.set(i,String(a));let r=o.toString();return r?`?${r}`:""}function A(s){return Object.prototype.toString.call(s)==="[object Object]"}function _(s={}){let o=q(s.baseUrl),r=s.fetch??(typeof fetch<"u"?fetch.bind(globalThis):void 0);if(!r)throw new Error("createObulClient requires a fetch implementation");let i=new b,a=null,p=e=>{let t=a;if(a=e,!t?.authenticated&&e.authenticated){i.emit("signed_in",e);return}if(t?.authenticated&&!e.authenticated){let n=typeof t.expiresAt=="number"&&t.expiresAt<=Date.now();i.emit(n?"session_expired":"signed_out",e)}},g=async()=>{let e=await r(`${o}/obul/session`,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!e.ok){let n={code:"session_fetch_failed",message:`Failed to fetch session (${e.status})`};return i.emit("error",n),{authenticated:!1}}let t=await e.json();return p(t),t},y=async e=>{if(typeof window>"u")return{ok:!1,error:{code:"not_in_browser",message:"handleCallback requires a browser environment"}};let t=await r(`${o}/obul/callback${window.location.search}`,{method:"GET",credentials:"include",headers:{Accept:"application/json","X-Obul-Client":"sdk-browser"}});if(!t.ok){let d={code:"callback_failed",message:`Callback failed (${t.status})`};return i.emit("error",d),{ok:!1,error:d}}let n=await t.json();return n.session&&p(n.session),e?.redirect!==!1&&n.redirectTo&&window.location.assign(n.redirectTo),n},O=()=>{if(typeof window>"u")return;let e=s.postLoginRedirect??window.location.href,t=new URL(`${o}/obul/login`,window.location.origin);t.searchParams.set("return_to",e),window.location.assign(t.toString())},w=async()=>{let e=E("obul_csrf"),t=await r(`${o}/obul/logout`,{method:"POST",credentials:"include",headers:{Accept:"application/json","Content-Type":"application/json","X-Obul-CSRF":e??""}});if(!t.ok){let n={code:"logout_failed",message:`Logout failed (${t.status})`};i.emit("error",n);return}p({authenticated:!1}),typeof window<"u"&&s.postLogoutRedirect&&window.location.assign(s.postLogoutRedirect)},l=async(e,t,n)=>{let h=t.startsWith("/")?t:`/${t}`,d=T(n?.query),u=new Headers(n?.headers??{});n?.maxPricePerRequest!=null&&u.set("X-Obul-Max-Price",String(n.maxPricePerRequest));let c;return n?.body!=null&&e!=="GET"&&e!=="HEAD"&&(n.body instanceof FormData||n.body instanceof Blob||n.body instanceof ArrayBuffer||typeof n.body=="string"?c=n.body:A(n.body)?(u.has("Content-Type")||u.set("Content-Type","application/json"),c=JSON.stringify(n.body)):(c=JSON.stringify(n.body),u.has("Content-Type")||u.set("Content-Type","application/json"))),r(`${o}/obul/api${h}${d}`,{method:e,credentials:"include",headers:u,body:c,signal:n?.signal})},m=s.sessionCheckIntervalMs??0;return m>0&&typeof window<"u"&&window.setInterval(()=>{g().catch(e=>i.emit("error",e))},m),{signIn:O,handleCallback:y,getSession:g,signOut:w,api:{request:(e,t,n)=>l(e,t,n),get:(e,t)=>l("GET",e,t),post:(e,t)=>l("POST",e,t),put:(e,t)=>l("PUT",e,t),patch:(e,t)=>l("PATCH",e,t),delete:(e,t)=>l("DELETE",e,t)},on:(e,t)=>i.on(e,t),off:(e,t)=>i.off(e,t)}}return P(j);})();
|
|
2
|
+
//# sourceMappingURL=obul-sdk.min.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/browser/index.ts"],
|
|
4
|
+
"sourcesContent": ["export type ObulSession = {\n authenticated: boolean\n expiresAt?: number\n limits?: {\n allowed_hosts: string[]\n max_price_per_request: number\n }\n}\n\nexport type ObulEventName = \"signed_in\" | \"signed_out\" | \"session_expired\" | \"error\"\n\nexport type ObulClientConfig = {\n baseUrl?: string\n postLoginRedirect?: string\n postLogoutRedirect?: string\n sessionCheckIntervalMs?: number\n fetch?: typeof fetch\n}\n\nexport type HandleCallbackResult = {\n ok: boolean\n redirectTo?: string\n session?: ObulSession\n error?: { code: string; message: string }\n}\n\nexport type ObulApiRequestOptions = {\n headers?: Record<string, string>\n query?: Record<string, string | number | boolean>\n maxPricePerRequest?: number\n body?: unknown\n signal?: AbortSignal\n}\n\nexport type ObulClient = {\n signIn: () => void\n handleCallback: (options?: { redirect?: boolean }) => Promise<HandleCallbackResult>\n getSession: () => Promise<ObulSession>\n signOut: () => Promise<void>\n api: {\n request: (method: string, path: string, options?: ObulApiRequestOptions) => Promise<Response>\n get: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n post: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n put: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n patch: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n delete: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n }\n on: (eventName: ObulEventName, handler: (payload?: unknown) => void) => void\n off: (eventName: ObulEventName, handler: (payload?: unknown) => void) => void\n}\n\ntype EventHandler = (payload?: unknown) => void\n\nclass Emitter {\n private listeners: Map<ObulEventName, Set<EventHandler>> = new Map()\n\n on(event: ObulEventName, handler: EventHandler) {\n const set = this.listeners.get(event) ?? new Set<EventHandler>()\n set.add(handler)\n this.listeners.set(event, set)\n }\n\n off(event: ObulEventName, handler: EventHandler) {\n const set = this.listeners.get(event)\n if (!set) return\n set.delete(handler)\n }\n\n emit(event: ObulEventName, payload?: unknown) {\n const set = this.listeners.get(event)\n if (!set) return\n for (const handler of set) handler(payload)\n }\n}\n\nfunction normalizeBaseUrl(baseUrl?: string): string {\n if (!baseUrl) return \"\"\n return baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl\n}\n\nfunction readCookie(name: string): string | undefined {\n if (typeof document === \"undefined\") return undefined\n const parts = document.cookie.split(\";\")\n for (const part of parts) {\n const [key, ...rest] = part.trim().split(\"=\")\n if (key === name) return decodeURIComponent(rest.join(\"=\"))\n }\n return undefined\n}\n\nfunction toQueryString(query?: Record<string, string | number | boolean>): string {\n if (!query) return \"\"\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n params.set(key, String(value))\n }\n const qs = params.toString()\n return qs ? `?${qs}` : \"\"\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Object.prototype.toString.call(value) === \"[object Object]\"\n}\n\nexport function createObulClient(config: ObulClientConfig = {}): ObulClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl)\n const fetcher = config.fetch ?? (typeof fetch !== \"undefined\" ? fetch.bind(globalThis) : undefined)\n if (!fetcher) {\n throw new Error(\"createObulClient requires a fetch implementation\")\n }\n\n const emitter = new Emitter()\n let currentSession: ObulSession | null = null\n\n const updateSession = (next: ObulSession) => {\n const prev = currentSession\n currentSession = next\n\n if (!prev?.authenticated && next.authenticated) {\n emitter.emit(\"signed_in\", next)\n return\n }\n\n if (prev?.authenticated && !next.authenticated) {\n const expired = typeof prev.expiresAt === \"number\" && prev.expiresAt <= Date.now()\n emitter.emit(expired ? \"session_expired\" : \"signed_out\", next)\n }\n }\n\n const getSession = async () => {\n const res = await fetcher(`${baseUrl}/obul/session`, {\n method: \"GET\",\n credentials: \"include\",\n headers: { Accept: \"application/json\" }\n })\n if (!res.ok) {\n const error = { code: \"session_fetch_failed\", message: `Failed to fetch session (${res.status})` }\n emitter.emit(\"error\", error)\n return { authenticated: false } as ObulSession\n }\n const session = (await res.json()) as ObulSession\n updateSession(session)\n return session\n }\n\n const handleCallback = async (options?: { redirect?: boolean }): Promise<HandleCallbackResult> => {\n if (typeof window === \"undefined\") {\n return { ok: false, error: { code: \"not_in_browser\", message: \"handleCallback requires a browser environment\" } }\n }\n\n const res = await fetcher(`${baseUrl}/obul/callback${window.location.search}`, {\n method: \"GET\",\n credentials: \"include\",\n headers: {\n Accept: \"application/json\",\n \"X-Obul-Client\": \"sdk-browser\"\n }\n })\n\n if (!res.ok) {\n const error = { code: \"callback_failed\", message: `Callback failed (${res.status})` }\n emitter.emit(\"error\", error)\n return { ok: false, error }\n }\n\n const data = (await res.json()) as HandleCallbackResult\n if (data.session) updateSession(data.session)\n\n const shouldRedirect = options?.redirect !== false\n if (shouldRedirect && data.redirectTo) window.location.assign(data.redirectTo)\n\n return data\n }\n\n const signIn = () => {\n if (typeof window === \"undefined\") return\n const returnTo = config.postLoginRedirect ?? window.location.href\n const url = new URL(`${baseUrl}/obul/login`, window.location.origin)\n url.searchParams.set(\"return_to\", returnTo)\n window.location.assign(url.toString())\n }\n\n const signOut = async () => {\n const csrf = readCookie(\"obul_csrf\")\n const res = await fetcher(`${baseUrl}/obul/logout`, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"X-Obul-CSRF\": csrf ?? \"\"\n }\n })\n\n if (!res.ok) {\n const error = { code: \"logout_failed\", message: `Logout failed (${res.status})` }\n emitter.emit(\"error\", error)\n return\n }\n\n updateSession({ authenticated: false })\n\n if (typeof window !== \"undefined\" && config.postLogoutRedirect) {\n window.location.assign(config.postLogoutRedirect)\n }\n }\n\n const apiRequest = async (method: string, path: string, options?: ObulApiRequestOptions) => {\n const normalized = path.startsWith(\"/\") ? path : `/${path}`\n const query = toQueryString(options?.query)\n const headers = new Headers(options?.headers ?? {})\n\n if (options?.maxPricePerRequest != null) {\n headers.set(\"X-Obul-Max-Price\", String(options.maxPricePerRequest))\n }\n\n let body: BodyInit | undefined\n if (options?.body != null && method !== \"GET\" && method !== \"HEAD\") {\n if (options.body instanceof FormData || options.body instanceof Blob) {\n body = options.body\n } else if (options.body instanceof ArrayBuffer) {\n body = options.body\n } else if (typeof options.body === \"string\") {\n body = options.body\n } else if (isPlainObject(options.body)) {\n if (!headers.has(\"Content-Type\")) headers.set(\"Content-Type\", \"application/json\")\n body = JSON.stringify(options.body)\n } else {\n body = JSON.stringify(options.body)\n if (!headers.has(\"Content-Type\")) headers.set(\"Content-Type\", \"application/json\")\n }\n }\n\n return fetcher(`${baseUrl}/obul/api${normalized}${query}`, {\n method,\n credentials: \"include\",\n headers,\n body,\n signal: options?.signal\n })\n }\n\n const intervalMs = config.sessionCheckIntervalMs ?? 0\n if (intervalMs > 0 && typeof window !== \"undefined\") {\n window.setInterval(() => {\n getSession().catch((error) => emitter.emit(\"error\", error))\n }, intervalMs)\n }\n\n return {\n signIn,\n handleCallback,\n getSession,\n signOut,\n api: {\n request: (method, path, options) => apiRequest(method, path, options),\n get: (path, options) => apiRequest(\"GET\", path, options),\n post: (path, options) => apiRequest(\"POST\", path, options),\n put: (path, options) => apiRequest(\"PUT\", path, options),\n patch: (path, options) => apiRequest(\"PATCH\", path, options),\n delete: (path, options) => apiRequest(\"DELETE\", path, options)\n },\n on: (eventName, handler) => emitter.on(eventName, handler),\n off: (eventName, handler) => emitter.off(eventName, handler)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["index_exports", "__export", "createObulClient", "Emitter", "event", "handler", "set", "payload", "normalizeBaseUrl", "baseUrl", "readCookie", "name", "parts", "part", "key", "rest", "toQueryString", "query", "params", "value", "qs", "isPlainObject", "config", "fetcher", "emitter", "currentSession", "updateSession", "next", "prev", "expired", "getSession", "res", "error", "session", "handleCallback", "options", "data", "signIn", "returnTo", "url", "signOut", "csrf", "apiRequest", "method", "path", "normalized", "headers", "body", "intervalMs", "eventName"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var f=class{constructor(){this.listeners=new Map}on(i,r){let s=this.listeners.get(i)??new Set;s.add(r),this.listeners.set(i,s)}off(i,r){let s=this.listeners.get(i);s&&s.delete(r)}emit(i,r){let s=this.listeners.get(i);if(s)for(let a of s)a(r)}};function w(o){return o?o.endsWith("/")?o.slice(0,-1):o:""}function R(o){if(typeof document>"u")return;let i=document.cookie.split(";");for(let r of i){let[s,...a]=r.trim().split("=");if(s===o)return decodeURIComponent(a.join("="))}}function k(o){if(!o)return"";let i=new URLSearchParams;for(let[s,a]of Object.entries(o))i.set(s,String(a));let r=i.toString();return r?`?${r}`:""}function v(o){return Object.prototype.toString.call(o)==="[object Object]"}function C(o={}){let i=w(o.baseUrl),r=o.fetch??(typeof fetch<"u"?fetch.bind(globalThis):void 0);if(!r)throw new Error("createObulClient requires a fetch implementation");let s=new f,a=null,p=e=>{let t=a;if(a=e,!t?.authenticated&&e.authenticated){s.emit("signed_in",e);return}if(t?.authenticated&&!e.authenticated){let n=typeof t.expiresAt=="number"&&t.expiresAt<=Date.now();s.emit(n?"session_expired":"signed_out",e)}},b=async()=>{let e=await r(`${i}/obul/session`,{method:"GET",credentials:"include",headers:{Accept:"application/json"}});if(!e.ok){let n={code:"session_fetch_failed",message:`Failed to fetch session (${e.status})`};return s.emit("error",n),{authenticated:!1}}let t=await e.json();return p(t),t},h=async e=>{if(typeof window>"u")return{ok:!1,error:{code:"not_in_browser",message:"handleCallback requires a browser environment"}};let t=await r(`${i}/obul/callback${window.location.search}`,{method:"GET",credentials:"include",headers:{Accept:"application/json","X-Obul-Client":"sdk-browser"}});if(!t.ok){let d={code:"callback_failed",message:`Callback failed (${t.status})`};return s.emit("error",d),{ok:!1,error:d}}let n=await t.json();return n.session&&p(n.session),e?.redirect!==!1&&n.redirectTo&&window.location.assign(n.redirectTo),n},y=()=>{if(typeof window>"u")return;let e=o.postLoginRedirect??window.location.href,t=new URL(`${i}/obul/login`,window.location.origin);t.searchParams.set("return_to",e),window.location.assign(t.toString())},O=async()=>{let e=R("obul_csrf"),t=await r(`${i}/obul/logout`,{method:"POST",credentials:"include",headers:{Accept:"application/json","Content-Type":"application/json","X-Obul-CSRF":e??""}});if(!t.ok){let n={code:"logout_failed",message:`Logout failed (${t.status})`};s.emit("error",n);return}p({authenticated:!1}),typeof window<"u"&&o.postLogoutRedirect&&window.location.assign(o.postLogoutRedirect)},l=async(e,t,n)=>{let m=t.startsWith("/")?t:`/${t}`,d=k(n?.query),u=new Headers(n?.headers??{});n?.maxPricePerRequest!=null&&u.set("X-Obul-Max-Price",String(n.maxPricePerRequest));let c;return n?.body!=null&&e!=="GET"&&e!=="HEAD"&&(n.body instanceof FormData||n.body instanceof Blob||n.body instanceof ArrayBuffer||typeof n.body=="string"?c=n.body:v(n.body)?(u.has("Content-Type")||u.set("Content-Type","application/json"),c=JSON.stringify(n.body)):(c=JSON.stringify(n.body),u.has("Content-Type")||u.set("Content-Type","application/json"))),r(`${i}/obul/api${m}${d}`,{method:e,credentials:"include",headers:u,body:c,signal:n?.signal})},g=o.sessionCheckIntervalMs??0;return g>0&&typeof window<"u"&&window.setInterval(()=>{b().catch(e=>s.emit("error",e))},g),{signIn:y,handleCallback:h,getSession:b,signOut:O,api:{request:(e,t,n)=>l(e,t,n),get:(e,t)=>l("GET",e,t),post:(e,t)=>l("POST",e,t),put:(e,t)=>l("PUT",e,t),patch:(e,t)=>l("PATCH",e,t),delete:(e,t)=>l("DELETE",e,t)},on:(e,t)=>s.on(e,t),off:(e,t)=>s.off(e,t)}}export{C as createObulClient};
|
|
2
|
+
//# sourceMappingURL=obul-sdk.min.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/browser/index.ts"],
|
|
4
|
+
"sourcesContent": ["export type ObulSession = {\n authenticated: boolean\n expiresAt?: number\n limits?: {\n allowed_hosts: string[]\n max_price_per_request: number\n }\n}\n\nexport type ObulEventName = \"signed_in\" | \"signed_out\" | \"session_expired\" | \"error\"\n\nexport type ObulClientConfig = {\n baseUrl?: string\n postLoginRedirect?: string\n postLogoutRedirect?: string\n sessionCheckIntervalMs?: number\n fetch?: typeof fetch\n}\n\nexport type HandleCallbackResult = {\n ok: boolean\n redirectTo?: string\n session?: ObulSession\n error?: { code: string; message: string }\n}\n\nexport type ObulApiRequestOptions = {\n headers?: Record<string, string>\n query?: Record<string, string | number | boolean>\n maxPricePerRequest?: number\n body?: unknown\n signal?: AbortSignal\n}\n\nexport type ObulClient = {\n signIn: () => void\n handleCallback: (options?: { redirect?: boolean }) => Promise<HandleCallbackResult>\n getSession: () => Promise<ObulSession>\n signOut: () => Promise<void>\n api: {\n request: (method: string, path: string, options?: ObulApiRequestOptions) => Promise<Response>\n get: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n post: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n put: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n patch: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n delete: (path: string, options?: ObulApiRequestOptions) => Promise<Response>\n }\n on: (eventName: ObulEventName, handler: (payload?: unknown) => void) => void\n off: (eventName: ObulEventName, handler: (payload?: unknown) => void) => void\n}\n\ntype EventHandler = (payload?: unknown) => void\n\nclass Emitter {\n private listeners: Map<ObulEventName, Set<EventHandler>> = new Map()\n\n on(event: ObulEventName, handler: EventHandler) {\n const set = this.listeners.get(event) ?? new Set<EventHandler>()\n set.add(handler)\n this.listeners.set(event, set)\n }\n\n off(event: ObulEventName, handler: EventHandler) {\n const set = this.listeners.get(event)\n if (!set) return\n set.delete(handler)\n }\n\n emit(event: ObulEventName, payload?: unknown) {\n const set = this.listeners.get(event)\n if (!set) return\n for (const handler of set) handler(payload)\n }\n}\n\nfunction normalizeBaseUrl(baseUrl?: string): string {\n if (!baseUrl) return \"\"\n return baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl\n}\n\nfunction readCookie(name: string): string | undefined {\n if (typeof document === \"undefined\") return undefined\n const parts = document.cookie.split(\";\")\n for (const part of parts) {\n const [key, ...rest] = part.trim().split(\"=\")\n if (key === name) return decodeURIComponent(rest.join(\"=\"))\n }\n return undefined\n}\n\nfunction toQueryString(query?: Record<string, string | number | boolean>): string {\n if (!query) return \"\"\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n params.set(key, String(value))\n }\n const qs = params.toString()\n return qs ? `?${qs}` : \"\"\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return Object.prototype.toString.call(value) === \"[object Object]\"\n}\n\nexport function createObulClient(config: ObulClientConfig = {}): ObulClient {\n const baseUrl = normalizeBaseUrl(config.baseUrl)\n const fetcher = config.fetch ?? (typeof fetch !== \"undefined\" ? fetch.bind(globalThis) : undefined)\n if (!fetcher) {\n throw new Error(\"createObulClient requires a fetch implementation\")\n }\n\n const emitter = new Emitter()\n let currentSession: ObulSession | null = null\n\n const updateSession = (next: ObulSession) => {\n const prev = currentSession\n currentSession = next\n\n if (!prev?.authenticated && next.authenticated) {\n emitter.emit(\"signed_in\", next)\n return\n }\n\n if (prev?.authenticated && !next.authenticated) {\n const expired = typeof prev.expiresAt === \"number\" && prev.expiresAt <= Date.now()\n emitter.emit(expired ? \"session_expired\" : \"signed_out\", next)\n }\n }\n\n const getSession = async () => {\n const res = await fetcher(`${baseUrl}/obul/session`, {\n method: \"GET\",\n credentials: \"include\",\n headers: { Accept: \"application/json\" }\n })\n if (!res.ok) {\n const error = { code: \"session_fetch_failed\", message: `Failed to fetch session (${res.status})` }\n emitter.emit(\"error\", error)\n return { authenticated: false } as ObulSession\n }\n const session = (await res.json()) as ObulSession\n updateSession(session)\n return session\n }\n\n const handleCallback = async (options?: { redirect?: boolean }): Promise<HandleCallbackResult> => {\n if (typeof window === \"undefined\") {\n return { ok: false, error: { code: \"not_in_browser\", message: \"handleCallback requires a browser environment\" } }\n }\n\n const res = await fetcher(`${baseUrl}/obul/callback${window.location.search}`, {\n method: \"GET\",\n credentials: \"include\",\n headers: {\n Accept: \"application/json\",\n \"X-Obul-Client\": \"sdk-browser\"\n }\n })\n\n if (!res.ok) {\n const error = { code: \"callback_failed\", message: `Callback failed (${res.status})` }\n emitter.emit(\"error\", error)\n return { ok: false, error }\n }\n\n const data = (await res.json()) as HandleCallbackResult\n if (data.session) updateSession(data.session)\n\n const shouldRedirect = options?.redirect !== false\n if (shouldRedirect && data.redirectTo) window.location.assign(data.redirectTo)\n\n return data\n }\n\n const signIn = () => {\n if (typeof window === \"undefined\") return\n const returnTo = config.postLoginRedirect ?? window.location.href\n const url = new URL(`${baseUrl}/obul/login`, window.location.origin)\n url.searchParams.set(\"return_to\", returnTo)\n window.location.assign(url.toString())\n }\n\n const signOut = async () => {\n const csrf = readCookie(\"obul_csrf\")\n const res = await fetcher(`${baseUrl}/obul/logout`, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"X-Obul-CSRF\": csrf ?? \"\"\n }\n })\n\n if (!res.ok) {\n const error = { code: \"logout_failed\", message: `Logout failed (${res.status})` }\n emitter.emit(\"error\", error)\n return\n }\n\n updateSession({ authenticated: false })\n\n if (typeof window !== \"undefined\" && config.postLogoutRedirect) {\n window.location.assign(config.postLogoutRedirect)\n }\n }\n\n const apiRequest = async (method: string, path: string, options?: ObulApiRequestOptions) => {\n const normalized = path.startsWith(\"/\") ? path : `/${path}`\n const query = toQueryString(options?.query)\n const headers = new Headers(options?.headers ?? {})\n\n if (options?.maxPricePerRequest != null) {\n headers.set(\"X-Obul-Max-Price\", String(options.maxPricePerRequest))\n }\n\n let body: BodyInit | undefined\n if (options?.body != null && method !== \"GET\" && method !== \"HEAD\") {\n if (options.body instanceof FormData || options.body instanceof Blob) {\n body = options.body\n } else if (options.body instanceof ArrayBuffer) {\n body = options.body\n } else if (typeof options.body === \"string\") {\n body = options.body\n } else if (isPlainObject(options.body)) {\n if (!headers.has(\"Content-Type\")) headers.set(\"Content-Type\", \"application/json\")\n body = JSON.stringify(options.body)\n } else {\n body = JSON.stringify(options.body)\n if (!headers.has(\"Content-Type\")) headers.set(\"Content-Type\", \"application/json\")\n }\n }\n\n return fetcher(`${baseUrl}/obul/api${normalized}${query}`, {\n method,\n credentials: \"include\",\n headers,\n body,\n signal: options?.signal\n })\n }\n\n const intervalMs = config.sessionCheckIntervalMs ?? 0\n if (intervalMs > 0 && typeof window !== \"undefined\") {\n window.setInterval(() => {\n getSession().catch((error) => emitter.emit(\"error\", error))\n }, intervalMs)\n }\n\n return {\n signIn,\n handleCallback,\n getSession,\n signOut,\n api: {\n request: (method, path, options) => apiRequest(method, path, options),\n get: (path, options) => apiRequest(\"GET\", path, options),\n post: (path, options) => apiRequest(\"POST\", path, options),\n put: (path, options) => apiRequest(\"PUT\", path, options),\n patch: (path, options) => apiRequest(\"PATCH\", path, options),\n delete: (path, options) => apiRequest(\"DELETE\", path, options)\n },\n on: (eventName, handler) => emitter.on(eventName, handler),\n off: (eventName, handler) => emitter.off(eventName, handler)\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Emitter", "event", "handler", "set", "payload", "normalizeBaseUrl", "baseUrl", "readCookie", "name", "parts", "part", "key", "rest", "toQueryString", "query", "params", "value", "qs", "isPlainObject", "createObulClient", "config", "fetcher", "emitter", "currentSession", "updateSession", "next", "prev", "expired", "getSession", "res", "error", "session", "handleCallback", "options", "data", "signIn", "returnTo", "url", "signOut", "csrf", "apiRequest", "method", "path", "normalized", "headers", "body", "intervalMs", "eventName"]
|
|
7
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@obul.ai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Single-package Obul BFF SDK facade with browser client, server core, and framework adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -40,11 +40,13 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
|
-
"dist"
|
|
43
|
+
"dist",
|
|
44
|
+
"README.md"
|
|
44
45
|
],
|
|
45
46
|
"sideEffects": false,
|
|
46
47
|
"scripts": {
|
|
47
|
-
"build": "tsc -p tsconfig.json",
|
|
48
|
+
"build": "tsc -p tsconfig.json && npm run build:browser",
|
|
49
|
+
"build:browser": "node ./scripts/build-browser.mjs",
|
|
48
50
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
49
51
|
},
|
|
50
52
|
"peerDependencies": {
|
|
@@ -54,15 +56,24 @@
|
|
|
54
56
|
"next": ">=13.0.0"
|
|
55
57
|
},
|
|
56
58
|
"peerDependenciesMeta": {
|
|
57
|
-
"cookie-parser": {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
59
|
+
"cookie-parser": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"express": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"hono": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"next": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
61
71
|
},
|
|
62
72
|
"devDependencies": {
|
|
63
73
|
"@types/cookie-parser": "^1.4.7",
|
|
64
74
|
"@types/express": "^4.17.21",
|
|
65
75
|
"@types/node": "^20.11.30",
|
|
76
|
+
"esbuild": "^0.24.2",
|
|
66
77
|
"hono": "^4.0.0"
|
|
67
78
|
}
|
|
68
|
-
}
|
|
79
|
+
}
|