bright-auth 0.1.0 → 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.
@@ -20,7 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  var src_exports = {};
21
21
  __export(src_exports, {
22
22
  BrightAuth: () => BrightAuth,
23
- default: () => src_default
23
+ default: () => src_default,
24
+ registerSignInButton: () => registerSignInButton
24
25
  });
25
26
  module.exports = __toCommonJS(src_exports);
26
27
  var DEFAULT_API_BASE = "https://api.thebrightapp.xyz/v1";
@@ -124,4 +125,49 @@ var BrightAuth = class {
124
125
  }
125
126
  };
126
127
  var src_default = BrightAuth;
128
+ function registerSignInButton() {
129
+ if (customElements.get("bright-signin")) return;
130
+ customElements.define("bright-signin", class BrightSignIn extends HTMLElement {
131
+ connectedCallback() {
132
+ const clientId = this.getAttribute("client-id") || "";
133
+ const clientSecret = this.getAttribute("client-secret") || "";
134
+ const redirectUri = this.getAttribute("redirect-uri") || "";
135
+ const scopes = (this.getAttribute("scopes") || "health").split(",").map((s) => s.trim());
136
+ const auth = new BrightAuth({ clientId, clientSecret, redirectUri });
137
+ const shadow = this.attachShadow({ mode: "closed" });
138
+ const style = document.createElement("style");
139
+ style.textContent = `
140
+ button {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ gap: 10px;
144
+ background: #10b981;
145
+ color: #fff;
146
+ border: none;
147
+ border-radius: 10px;
148
+ padding: 12px 20px;
149
+ font-size: 14px;
150
+ font-weight: 600;
151
+ font-family: system-ui, -apple-system, sans-serif;
152
+ cursor: pointer;
153
+ transition: opacity 0.15s;
154
+ white-space: nowrap;
155
+ }
156
+ button:hover { opacity: 0.85; }
157
+ button:active { opacity: 0.7; transform: scale(0.98); }
158
+ svg { flex-shrink: 0; }
159
+ `;
160
+ const btn = document.createElement("button");
161
+ btn.innerHTML = `
162
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
163
+ <circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/>
164
+ </svg>
165
+ Sign in with Bright
166
+ `;
167
+ btn.addEventListener("click", () => auth.signIn(scopes));
168
+ shadow.appendChild(style);
169
+ shadow.appendChild(btn);
170
+ }
171
+ });
172
+ }
127
173
  //# sourceMappingURL=bright-auth.cjs.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.js"],
4
- "sourcesContent": ["const DEFAULT_API_BASE = \"https://api.thebrightapp.xyz/v1\"\nconst DEFAULT_AUTH_BASE = \"https://developers.thebrightapp.xyz\"\nconst TOKEN_KEY = \"bright_access_token\"\n\nexport class BrightAuth {\n /**\n * @param {{ clientId: string, clientSecret: string, redirectUri: string, apiBase?: string, authBase?: string }} config\n */\n constructor({ clientId, clientSecret, redirectUri, apiBase, authBase } = {}) {\n if (!clientId) throw new Error(\"BrightAuth: clientId is required\")\n if (!clientSecret) throw new Error(\"BrightAuth: clientSecret is required\")\n if (!redirectUri) throw new Error(\"BrightAuth: redirectUri is required\")\n\n this._clientId = clientId\n this._clientSecret = clientSecret\n this._redirectUri = redirectUri\n this._apiBase = (apiBase || DEFAULT_API_BASE).replace(/\\/$/, \"\")\n this._authBase = (authBase || DEFAULT_AUTH_BASE).replace(/\\/$/, \"\")\n }\n\n /** Redirect the user to the Bright consent page. */\n signIn(scopes = [\"health\"]) {\n const url = new URL(`${this._authBase}/oauth/authorize`)\n url.searchParams.set(\"client_id\", this._clientId)\n url.searchParams.set(\"redirect_uri\", this._redirectUri)\n scopes.forEach(s => url.searchParams.append(\"scope\", s))\n window.location.href = url.toString()\n }\n\n /**\n * Call on every page load. If the URL contains ?code=, exchanges it for an\n * access token, stores it, and cleans the URL.\n * @returns {Promise<string|null>} The access token, or null if no code in URL.\n */\n async handleCallback() {\n const params = new URLSearchParams(window.location.search)\n const code = params.get(\"code\")\n const error = params.get(\"error\")\n\n if (error) throw new Error(`Bright OAuth error: ${error}`)\n if (!code) return null\n\n window.history.replaceState({}, \"\", window.location.pathname)\n\n const res = await fetch(`${this._apiBase}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_id: this._clientId,\n client_secret: this._clientSecret,\n code,\n }),\n })\n const data = await res.json()\n if (!res.ok) throw new Error(data.detail || \"Token exchange failed\")\n\n localStorage.setItem(TOKEN_KEY, data.access_token)\n return data.access_token\n }\n\n /** Returns the stored access token, or null if not signed in. */\n getToken() {\n return localStorage.getItem(TOKEN_KEY)\n }\n\n /** Remove the stored token (signs the user out locally). */\n signOut() {\n localStorage.removeItem(TOKEN_KEY)\n }\n\n /** Returns true if an access token is stored. */\n isSignedIn() {\n return !!this.getToken()\n }\n\n /**\n * Fetch the signed-in user's identity from Bright.\n * @returns {Promise<{ uid: string, email?: string, name?: string, photo_url?: string }>}\n */\n async getUser() {\n return this._call(\"/oauth/me\")\n }\n\n /**\n * Make an authenticated request to any Bright API endpoint.\n * @param {string} path e.g. \"/sleep_track/home\"\n * @param {object} [init] fetch options (method, body, etc.)\n * @param {object} [query] query params object\n */\n async fetch(path, init = {}, query = {}) {\n const token = this.getToken()\n if (!token) throw new Error(\"BrightAuth: not signed in\")\n\n const url = new URL(`${this._apiBase}${path}`)\n Object.entries(query).forEach(([k, v]) => url.searchParams.set(k, v))\n\n const res = await globalThis.fetch(url.toString(), {\n ...init,\n headers: {\n ...(init.headers || {}),\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n })\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}))\n throw new Error(err.detail || `Bright API error ${res.status}`)\n }\n return res.json()\n }\n\n /** @private */\n async _call(path, query = {}) {\n return this.fetch(path, {}, query)\n }\n}\n\nexport default BrightAuth\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["const DEFAULT_API_BASE = \"https://api.thebrightapp.xyz/v1\"\nconst DEFAULT_AUTH_BASE = \"https://developers.thebrightapp.xyz\"\nconst TOKEN_KEY = \"bright_access_token\"\n\nexport class BrightAuth {\n /**\n * @param {{ clientId: string, clientSecret: string, redirectUri: string, apiBase?: string, authBase?: string }} config\n */\n constructor({ clientId, clientSecret, redirectUri, apiBase, authBase } = {}) {\n if (!clientId) throw new Error(\"BrightAuth: clientId is required\")\n if (!clientSecret) throw new Error(\"BrightAuth: clientSecret is required\")\n if (!redirectUri) throw new Error(\"BrightAuth: redirectUri is required\")\n\n this._clientId = clientId\n this._clientSecret = clientSecret\n this._redirectUri = redirectUri\n this._apiBase = (apiBase || DEFAULT_API_BASE).replace(/\\/$/, \"\")\n this._authBase = (authBase || DEFAULT_AUTH_BASE).replace(/\\/$/, \"\")\n }\n\n /** Redirect the user to the Bright consent page. */\n signIn(scopes = [\"health\"]) {\n const url = new URL(`${this._authBase}/oauth/authorize`)\n url.searchParams.set(\"client_id\", this._clientId)\n url.searchParams.set(\"redirect_uri\", this._redirectUri)\n scopes.forEach(s => url.searchParams.append(\"scope\", s))\n window.location.href = url.toString()\n }\n\n /**\n * Call on every page load. If the URL contains ?code=, exchanges it for an\n * access token, stores it, and cleans the URL.\n * @returns {Promise<string|null>} The access token, or null if no code in URL.\n */\n async handleCallback() {\n const params = new URLSearchParams(window.location.search)\n const code = params.get(\"code\")\n const error = params.get(\"error\")\n\n if (error) throw new Error(`Bright OAuth error: ${error}`)\n if (!code) return null\n\n window.history.replaceState({}, \"\", window.location.pathname)\n\n const res = await fetch(`${this._apiBase}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_id: this._clientId,\n client_secret: this._clientSecret,\n code,\n }),\n })\n const data = await res.json()\n if (!res.ok) throw new Error(data.detail || \"Token exchange failed\")\n\n localStorage.setItem(TOKEN_KEY, data.access_token)\n return data.access_token\n }\n\n /** Returns the stored access token, or null if not signed in. */\n getToken() {\n return localStorage.getItem(TOKEN_KEY)\n }\n\n /** Remove the stored token (signs the user out locally). */\n signOut() {\n localStorage.removeItem(TOKEN_KEY)\n }\n\n /** Returns true if an access token is stored. */\n isSignedIn() {\n return !!this.getToken()\n }\n\n /**\n * Fetch the signed-in user's identity from Bright.\n * @returns {Promise<{ uid: string, email?: string, name?: string, photo_url?: string }>}\n */\n async getUser() {\n return this._call(\"/oauth/me\")\n }\n\n /**\n * Make an authenticated request to any Bright API endpoint.\n * @param {string} path e.g. \"/sleep_track/home\"\n * @param {object} [init] fetch options (method, body, etc.)\n * @param {object} [query] query params object\n */\n async fetch(path, init = {}, query = {}) {\n const token = this.getToken()\n if (!token) throw new Error(\"BrightAuth: not signed in\")\n\n const url = new URL(`${this._apiBase}${path}`)\n Object.entries(query).forEach(([k, v]) => url.searchParams.set(k, v))\n\n const res = await globalThis.fetch(url.toString(), {\n ...init,\n headers: {\n ...(init.headers || {}),\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n })\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}))\n throw new Error(err.detail || `Bright API error ${res.status}`)\n }\n return res.json()\n }\n\n /** @private */\n async _call(path, query = {}) {\n return this.fetch(path, {}, query)\n }\n}\n\nexport default BrightAuth\n\n/**\n * Registers the <bright-signin> custom element.\n * Styling is locked inside Shadow DOM \u2014 cannot be overridden by the host page.\n *\n * Usage:\n * <bright-signin client-id=\"proj_xxx\" client-secret=\"sk_xxx\" redirect-uri=\"https://yourapp.com\"></bright-signin>\n *\n * Or via JS:\n * registerSignInButton()\n * // then use <bright-signin> in your HTML\n */\nexport function registerSignInButton() {\n if (customElements.get(\"bright-signin\")) return\n\n customElements.define(\"bright-signin\", class BrightSignIn extends HTMLElement {\n connectedCallback() {\n const clientId = this.getAttribute(\"client-id\") || \"\"\n const clientSecret = this.getAttribute(\"client-secret\") || \"\"\n const redirectUri = this.getAttribute(\"redirect-uri\") || \"\"\n const scopes = (this.getAttribute(\"scopes\") || \"health\").split(\",\").map(s => s.trim())\n\n const auth = new BrightAuth({ clientId, clientSecret, redirectUri })\n\n const shadow = this.attachShadow({ mode: \"closed\" })\n\n const style = document.createElement(\"style\")\n style.textContent = `\n button {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n background: #10b981;\n color: #fff;\n border: none;\n border-radius: 10px;\n padding: 12px 20px;\n font-size: 14px;\n font-weight: 600;\n font-family: system-ui, -apple-system, sans-serif;\n cursor: pointer;\n transition: opacity 0.15s;\n white-space: nowrap;\n }\n button:hover { opacity: 0.85; }\n button:active { opacity: 0.7; transform: scale(0.98); }\n svg { flex-shrink: 0; }\n `\n\n const btn = document.createElement(\"button\")\n btn.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\"/>\n </svg>\n Sign in with Bright\n `\n btn.addEventListener(\"click\", () => auth.signIn(scopes))\n\n shadow.appendChild(style)\n shadow.appendChild(btn)\n }\n })\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -100,8 +100,54 @@ var BrightAuth = class {
100
100
  }
101
101
  };
102
102
  var src_default = BrightAuth;
103
+ function registerSignInButton() {
104
+ if (customElements.get("bright-signin")) return;
105
+ customElements.define("bright-signin", class BrightSignIn extends HTMLElement {
106
+ connectedCallback() {
107
+ const clientId = this.getAttribute("client-id") || "";
108
+ const clientSecret = this.getAttribute("client-secret") || "";
109
+ const redirectUri = this.getAttribute("redirect-uri") || "";
110
+ const scopes = (this.getAttribute("scopes") || "health").split(",").map((s) => s.trim());
111
+ const auth = new BrightAuth({ clientId, clientSecret, redirectUri });
112
+ const shadow = this.attachShadow({ mode: "closed" });
113
+ const style = document.createElement("style");
114
+ style.textContent = `
115
+ button {
116
+ display: inline-flex;
117
+ align-items: center;
118
+ gap: 10px;
119
+ background: #10b981;
120
+ color: #fff;
121
+ border: none;
122
+ border-radius: 10px;
123
+ padding: 12px 20px;
124
+ font-size: 14px;
125
+ font-weight: 600;
126
+ font-family: system-ui, -apple-system, sans-serif;
127
+ cursor: pointer;
128
+ transition: opacity 0.15s;
129
+ white-space: nowrap;
130
+ }
131
+ button:hover { opacity: 0.85; }
132
+ button:active { opacity: 0.7; transform: scale(0.98); }
133
+ svg { flex-shrink: 0; }
134
+ `;
135
+ const btn = document.createElement("button");
136
+ btn.innerHTML = `
137
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
138
+ <circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/>
139
+ </svg>
140
+ Sign in with Bright
141
+ `;
142
+ btn.addEventListener("click", () => auth.signIn(scopes));
143
+ shadow.appendChild(style);
144
+ shadow.appendChild(btn);
145
+ }
146
+ });
147
+ }
103
148
  export {
104
149
  BrightAuth,
105
- src_default as default
150
+ src_default as default,
151
+ registerSignInButton
106
152
  };
107
153
  //# sourceMappingURL=bright-auth.esm.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.js"],
4
- "sourcesContent": ["const DEFAULT_API_BASE = \"https://api.thebrightapp.xyz/v1\"\nconst DEFAULT_AUTH_BASE = \"https://developers.thebrightapp.xyz\"\nconst TOKEN_KEY = \"bright_access_token\"\n\nexport class BrightAuth {\n /**\n * @param {{ clientId: string, clientSecret: string, redirectUri: string, apiBase?: string, authBase?: string }} config\n */\n constructor({ clientId, clientSecret, redirectUri, apiBase, authBase } = {}) {\n if (!clientId) throw new Error(\"BrightAuth: clientId is required\")\n if (!clientSecret) throw new Error(\"BrightAuth: clientSecret is required\")\n if (!redirectUri) throw new Error(\"BrightAuth: redirectUri is required\")\n\n this._clientId = clientId\n this._clientSecret = clientSecret\n this._redirectUri = redirectUri\n this._apiBase = (apiBase || DEFAULT_API_BASE).replace(/\\/$/, \"\")\n this._authBase = (authBase || DEFAULT_AUTH_BASE).replace(/\\/$/, \"\")\n }\n\n /** Redirect the user to the Bright consent page. */\n signIn(scopes = [\"health\"]) {\n const url = new URL(`${this._authBase}/oauth/authorize`)\n url.searchParams.set(\"client_id\", this._clientId)\n url.searchParams.set(\"redirect_uri\", this._redirectUri)\n scopes.forEach(s => url.searchParams.append(\"scope\", s))\n window.location.href = url.toString()\n }\n\n /**\n * Call on every page load. If the URL contains ?code=, exchanges it for an\n * access token, stores it, and cleans the URL.\n * @returns {Promise<string|null>} The access token, or null if no code in URL.\n */\n async handleCallback() {\n const params = new URLSearchParams(window.location.search)\n const code = params.get(\"code\")\n const error = params.get(\"error\")\n\n if (error) throw new Error(`Bright OAuth error: ${error}`)\n if (!code) return null\n\n window.history.replaceState({}, \"\", window.location.pathname)\n\n const res = await fetch(`${this._apiBase}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_id: this._clientId,\n client_secret: this._clientSecret,\n code,\n }),\n })\n const data = await res.json()\n if (!res.ok) throw new Error(data.detail || \"Token exchange failed\")\n\n localStorage.setItem(TOKEN_KEY, data.access_token)\n return data.access_token\n }\n\n /** Returns the stored access token, or null if not signed in. */\n getToken() {\n return localStorage.getItem(TOKEN_KEY)\n }\n\n /** Remove the stored token (signs the user out locally). */\n signOut() {\n localStorage.removeItem(TOKEN_KEY)\n }\n\n /** Returns true if an access token is stored. */\n isSignedIn() {\n return !!this.getToken()\n }\n\n /**\n * Fetch the signed-in user's identity from Bright.\n * @returns {Promise<{ uid: string, email?: string, name?: string, photo_url?: string }>}\n */\n async getUser() {\n return this._call(\"/oauth/me\")\n }\n\n /**\n * Make an authenticated request to any Bright API endpoint.\n * @param {string} path e.g. \"/sleep_track/home\"\n * @param {object} [init] fetch options (method, body, etc.)\n * @param {object} [query] query params object\n */\n async fetch(path, init = {}, query = {}) {\n const token = this.getToken()\n if (!token) throw new Error(\"BrightAuth: not signed in\")\n\n const url = new URL(`${this._apiBase}${path}`)\n Object.entries(query).forEach(([k, v]) => url.searchParams.set(k, v))\n\n const res = await globalThis.fetch(url.toString(), {\n ...init,\n headers: {\n ...(init.headers || {}),\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n })\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}))\n throw new Error(err.detail || `Bright API error ${res.status}`)\n }\n return res.json()\n }\n\n /** @private */\n async _call(path, query = {}) {\n return this.fetch(path, {}, query)\n }\n}\n\nexport default BrightAuth\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["const DEFAULT_API_BASE = \"https://api.thebrightapp.xyz/v1\"\nconst DEFAULT_AUTH_BASE = \"https://developers.thebrightapp.xyz\"\nconst TOKEN_KEY = \"bright_access_token\"\n\nexport class BrightAuth {\n /**\n * @param {{ clientId: string, clientSecret: string, redirectUri: string, apiBase?: string, authBase?: string }} config\n */\n constructor({ clientId, clientSecret, redirectUri, apiBase, authBase } = {}) {\n if (!clientId) throw new Error(\"BrightAuth: clientId is required\")\n if (!clientSecret) throw new Error(\"BrightAuth: clientSecret is required\")\n if (!redirectUri) throw new Error(\"BrightAuth: redirectUri is required\")\n\n this._clientId = clientId\n this._clientSecret = clientSecret\n this._redirectUri = redirectUri\n this._apiBase = (apiBase || DEFAULT_API_BASE).replace(/\\/$/, \"\")\n this._authBase = (authBase || DEFAULT_AUTH_BASE).replace(/\\/$/, \"\")\n }\n\n /** Redirect the user to the Bright consent page. */\n signIn(scopes = [\"health\"]) {\n const url = new URL(`${this._authBase}/oauth/authorize`)\n url.searchParams.set(\"client_id\", this._clientId)\n url.searchParams.set(\"redirect_uri\", this._redirectUri)\n scopes.forEach(s => url.searchParams.append(\"scope\", s))\n window.location.href = url.toString()\n }\n\n /**\n * Call on every page load. If the URL contains ?code=, exchanges it for an\n * access token, stores it, and cleans the URL.\n * @returns {Promise<string|null>} The access token, or null if no code in URL.\n */\n async handleCallback() {\n const params = new URLSearchParams(window.location.search)\n const code = params.get(\"code\")\n const error = params.get(\"error\")\n\n if (error) throw new Error(`Bright OAuth error: ${error}`)\n if (!code) return null\n\n window.history.replaceState({}, \"\", window.location.pathname)\n\n const res = await fetch(`${this._apiBase}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_id: this._clientId,\n client_secret: this._clientSecret,\n code,\n }),\n })\n const data = await res.json()\n if (!res.ok) throw new Error(data.detail || \"Token exchange failed\")\n\n localStorage.setItem(TOKEN_KEY, data.access_token)\n return data.access_token\n }\n\n /** Returns the stored access token, or null if not signed in. */\n getToken() {\n return localStorage.getItem(TOKEN_KEY)\n }\n\n /** Remove the stored token (signs the user out locally). */\n signOut() {\n localStorage.removeItem(TOKEN_KEY)\n }\n\n /** Returns true if an access token is stored. */\n isSignedIn() {\n return !!this.getToken()\n }\n\n /**\n * Fetch the signed-in user's identity from Bright.\n * @returns {Promise<{ uid: string, email?: string, name?: string, photo_url?: string }>}\n */\n async getUser() {\n return this._call(\"/oauth/me\")\n }\n\n /**\n * Make an authenticated request to any Bright API endpoint.\n * @param {string} path e.g. \"/sleep_track/home\"\n * @param {object} [init] fetch options (method, body, etc.)\n * @param {object} [query] query params object\n */\n async fetch(path, init = {}, query = {}) {\n const token = this.getToken()\n if (!token) throw new Error(\"BrightAuth: not signed in\")\n\n const url = new URL(`${this._apiBase}${path}`)\n Object.entries(query).forEach(([k, v]) => url.searchParams.set(k, v))\n\n const res = await globalThis.fetch(url.toString(), {\n ...init,\n headers: {\n ...(init.headers || {}),\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n })\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}))\n throw new Error(err.detail || `Bright API error ${res.status}`)\n }\n return res.json()\n }\n\n /** @private */\n async _call(path, query = {}) {\n return this.fetch(path, {}, query)\n }\n}\n\nexport default BrightAuth\n\n/**\n * Registers the <bright-signin> custom element.\n * Styling is locked inside Shadow DOM \u2014 cannot be overridden by the host page.\n *\n * Usage:\n * <bright-signin client-id=\"proj_xxx\" client-secret=\"sk_xxx\" redirect-uri=\"https://yourapp.com\"></bright-signin>\n *\n * Or via JS:\n * registerSignInButton()\n * // then use <bright-signin> in your HTML\n */\nexport function registerSignInButton() {\n if (customElements.get(\"bright-signin\")) return\n\n customElements.define(\"bright-signin\", class BrightSignIn extends HTMLElement {\n connectedCallback() {\n const clientId = this.getAttribute(\"client-id\") || \"\"\n const clientSecret = this.getAttribute(\"client-secret\") || \"\"\n const redirectUri = this.getAttribute(\"redirect-uri\") || \"\"\n const scopes = (this.getAttribute(\"scopes\") || \"health\").split(\",\").map(s => s.trim())\n\n const auth = new BrightAuth({ clientId, clientSecret, redirectUri })\n\n const shadow = this.attachShadow({ mode: \"closed\" })\n\n const style = document.createElement(\"style\")\n style.textContent = `\n button {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n background: #10b981;\n color: #fff;\n border: none;\n border-radius: 10px;\n padding: 12px 20px;\n font-size: 14px;\n font-weight: 600;\n font-family: system-ui, -apple-system, sans-serif;\n cursor: pointer;\n transition: opacity 0.15s;\n white-space: nowrap;\n }\n button:hover { opacity: 0.85; }\n button:active { opacity: 0.7; transform: scale(0.98); }\n svg { flex-shrink: 0; }\n `\n\n const btn = document.createElement(\"button\")\n btn.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\n <circle cx=\"12\" cy=\"8\" r=\"4\"/><path d=\"M4 20c0-4 3.6-7 8-7s8 3 8 7\"/>\n </svg>\n Sign in with Bright\n `\n btn.addEventListener(\"click\", () => auth.signIn(scopes))\n\n shadow.appendChild(style)\n shadow.appendChild(btn)\n }\n })\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bright-auth",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Sign in with Bright — OAuth SDK for web",
5
5
  "main": "dist/bright-auth.cjs.js",
6
6
  "module": "dist/bright-auth.esm.js",