@lovable.dev/cloud-auth-js 1.1.3-rc.9 → 1.2.1

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 CHANGED
@@ -32,6 +32,28 @@ if (result.error) {
32
32
  await supabase.auth.setSession(result.tokens);
33
33
  ```
34
34
 
35
+ ### Sign in with Lovable button
36
+
37
+ Import the first-party stylesheet and apply its class to the button that invokes the Lovable provider:
38
+
39
+ ```tsx
40
+ import "@lovable.dev/cloud-auth-js/styles.css";
41
+ <button type="button" className="lovable-auth-button lovable-auth-button--full-width" onClick={handleLovableSignIn}>
42
+ Continue with Lovable
43
+ </button>;
44
+ ```
45
+
46
+ Use the `signInWithOAuth` flow above with `"lovable"` in `handleLovableSignIn`. Add
47
+ `lovable-auth-button--dark` on dark surfaces. The stylesheet owns the official mark, provider spacing, colors, focus
48
+ treatment, and disabled state.
49
+
50
+ For a custom button, import the heart mark separately:
51
+
52
+ ```tsx
53
+ import lovableMarkUrl from "@lovable.dev/cloud-auth-js/lovable-mark.svg";
54
+ <img src={lovableMarkUrl} alt="" />;
55
+ ```
56
+
35
57
  ## API
36
58
 
37
59
  ### `createLovableAuth(config?)`
@@ -0,0 +1,16 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="121" height="122" viewBox="0 0 121 122" fill="none">
2
+ <clipPath id="mask0_572_319" clipPathUnits="userSpaceOnUse"><path clip-rule="evenodd" d="M36.0687 0C55.9888 0 72.1373 16.1551 72.1373 36.0835V49.7975H84.141C104.061 49.7975 120.21 65.9526 120.21 85.8809C120.21 105.809 104.061 121.964 84.141 121.964H0V36.0835C0 16.1551 16.1485 0 36.0687 0Z"/></clipPath>
3
+ <g clip-path="url(#mask0_572_319)">
4
+ <rect x="0" y="0" width="121" height="122" fill="url(#blur0_f_572_319)"/>
5
+ <rect x="0" y="0" width="121" height="122" fill="url(#blur1_f_572_319)"/>
6
+ <rect x="0" y="0" width="121" height="122" fill="url(#blur2_f_572_319)"/>
7
+ <rect x="0" y="0" width="121" height="122" fill="url(#blur3_f_572_319)"/>
8
+ </g>
9
+ <defs>
10
+
11
+
12
+
13
+
14
+
15
+ <radialGradient id="blur0_f_572_319" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(141.41178 0 0 141.23118 52.7381 65.1011)"><stop offset="0" stop-color="#4B73FF" stop-opacity="1"/><stop offset="0.17" stop-color="#4B73FF" stop-opacity="0.9984"/><stop offset="0.25" stop-color="#4B73FF" stop-opacity="0.9908"/><stop offset="0.31" stop-color="#4B73FF" stop-opacity="0.972"/><stop offset="0.335" stop-color="#4B73FF" stop-opacity="0.9575"/><stop offset="0.365" stop-color="#4B73FF" stop-opacity="0.9325"/><stop offset="0.39" stop-color="#4B73FF" stop-opacity="0.9039"/><stop offset="0.415" stop-color="#4B73FF" stop-opacity="0.8667"/><stop offset="0.44" stop-color="#4B73FF" stop-opacity="0.8218"/><stop offset="0.465" stop-color="#4B73FF" stop-opacity="0.7674"/><stop offset="0.48" stop-color="#4B73FF" stop-opacity="0.7315"/><stop offset="0.52" stop-color="#4B73FF" stop-opacity="0.6221"/><stop offset="0.59" stop-color="#4B73FF" stop-opacity="0.4091"/><stop offset="0.61" stop-color="#4B73FF" stop-opacity="0.3547"/><stop offset="0.615" stop-color="#4B73FF" stop-opacity="0.3352"/><stop offset="0.625" stop-color="#4B73FF" stop-opacity="0.3119"/><stop offset="0.63" stop-color="#4B73FF" stop-opacity="0.2942"/><stop offset="0.65" stop-color="#4B73FF" stop-opacity="0.2477"/><stop offset="0.655" stop-color="#4B73FF" stop-opacity="0.2306"/><stop offset="0.69" stop-color="#4B73FF" stop-opacity="0.1597"/><stop offset="0.71" stop-color="#4B73FF" stop-opacity="0.1249"/><stop offset="0.735" stop-color="#4B73FF" stop-opacity="0.0898"/><stop offset="0.76" stop-color="#4B73FF" stop-opacity="0.0623"/><stop offset="0.785" stop-color="#4B73FF" stop-opacity="0.0418"/><stop offset="0.815" stop-color="#4B73FF" stop-opacity="0.025"/><stop offset="0.89" stop-color="#4B73FF" stop-opacity="0.0056"/><stop offset="1" stop-color="#4B73FF" stop-opacity="0"/></radialGradient><radialGradient id="blur1_f_572_319" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(164.25488 0 0 141.23118 61.6734 20.547)"><stop offset="0" stop-color="#FF66F4" stop-opacity="1"/><stop offset="0.19" stop-color="#FF66F4" stop-opacity="0.9992"/><stop offset="0.275" stop-color="#FF66F4" stop-opacity="0.9945"/><stop offset="0.345" stop-color="#FF66F4" stop-opacity="0.9778"/><stop offset="0.38" stop-color="#FF66F4" stop-opacity="0.9553"/><stop offset="0.405" stop-color="#FF66F4" stop-opacity="0.922"/><stop offset="0.44" stop-color="#FF66F4" stop-opacity="0.8652"/><stop offset="0.475" stop-color="#FF66F4" stop-opacity="0.7911"/><stop offset="0.51" stop-color="#FF66F4" stop-opacity="0.698"/><stop offset="0.535" stop-color="#FF66F4" stop-opacity="0.6239"/><stop offset="0.615" stop-color="#FF66F4" stop-opacity="0.3691"/><stop offset="0.65" stop-color="#FF66F4" stop-opacity="0.2693"/><stop offset="0.69" stop-color="#FF66F4" stop-opacity="0.1761"/><stop offset="0.725" stop-color="#FF66F4" stop-opacity="0.1144"/><stop offset="0.755" stop-color="#FF66F4" stop-opacity="0.0768"/><stop offset="0.78" stop-color="#FF66F4" stop-opacity="0.053"/><stop offset="0.8" stop-color="#FF66F4" stop-opacity="0.0384"/><stop offset="0.84" stop-color="#FF66F4" stop-opacity="0.0208"/><stop offset="0.9" stop-color="#FF66F4" stop-opacity="0.0056"/><stop offset="1" stop-color="#FF66F4" stop-opacity="0"/></radialGradient><radialGradient id="blur2_f_572_319" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(141.41178 0 0 131.34308 78.6659 5.26802)"><stop offset="0" stop-color="#FF0105" stop-opacity="0.9998"/><stop offset="0.14" stop-color="#FF0105" stop-opacity="0.9981"/><stop offset="0.225" stop-color="#FF0105" stop-opacity="0.9894"/><stop offset="0.26" stop-color="#FF0105" stop-opacity="0.9802"/><stop offset="0.295" stop-color="#FF0105" stop-opacity="0.9645"/><stop offset="0.34" stop-color="#FF0105" stop-opacity="0.9277"/><stop offset="0.365" stop-color="#FF0105" stop-opacity="0.899"/><stop offset="0.395" stop-color="#FF0105" stop-opacity="0.8549"/><stop offset="0.42" stop-color="#FF0105" stop-opacity="0.8098"/><stop offset="0.44" stop-color="#FF0105" stop-opacity="0.7683"/><stop offset="0.48" stop-color="#FF0105" stop-opacity="0.6713"/><stop offset="0.555" stop-color="#FF0105" stop-opacity="0.4582"/><stop offset="0.57" stop-color="#FF0105" stop-opacity="0.4086"/><stop offset="0.59" stop-color="#FF0105" stop-opacity="0.3497"/><stop offset="0.625" stop-color="#FF0105" stop-opacity="0.2585"/><stop offset="0.665" stop-color="#FF0105" stop-opacity="0.1721"/><stop offset="0.685" stop-color="#FF0105" stop-opacity="0.1367"/><stop offset="0.705" stop-color="#FF0105" stop-opacity="0.1076"/><stop offset="0.725" stop-color="#FF0105" stop-opacity="0.0827"/><stop offset="0.765" stop-color="#FF0105" stop-opacity="0.0465"/><stop offset="0.81" stop-color="#FF0105" stop-opacity="0.0226"/><stop offset="0.885" stop-color="#FF0105" stop-opacity="0.0054"/><stop offset="1" stop-color="#FF0105" stop-opacity="0"/></radialGradient><radialGradient id="blur3_f_572_319" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(108.97628 0 0 108.86768 63.121 20.5275)"><stop offset="0" stop-color="#FE7B02" stop-opacity="0.9728"/><stop offset="0.075" stop-color="#FE7B02" stop-opacity="0.9627"/><stop offset="0.135" stop-color="#FE7B02" stop-opacity="0.9373"/><stop offset="0.16" stop-color="#FE7B02" stop-opacity="0.9211"/><stop offset="0.2" stop-color="#FE7B02" stop-opacity="0.8856"/><stop offset="0.25" stop-color="#FE7B02" stop-opacity="0.825"/><stop offset="0.295" stop-color="#FE7B02" stop-opacity="0.7538"/><stop offset="0.35" stop-color="#FE7B02" stop-opacity="0.6472"/><stop offset="0.395" stop-color="#FE7B02" stop-opacity="0.5483"/><stop offset="0.45" stop-color="#FE7B02" stop-opacity="0.4201"/><stop offset="0.525" stop-color="#FE7B02" stop-opacity="0.2629"/><stop offset="0.57" stop-color="#FE7B02" stop-opacity="0.1851"/><stop offset="0.595" stop-color="#FE7B02" stop-opacity="0.1489"/><stop offset="0.645" stop-color="#FE7B02" stop-opacity="0.0913"/><stop offset="0.7" stop-color="#FE7B02" stop-opacity="0.0489"/><stop offset="0.77" stop-color="#FE7B02" stop-opacity="0.0193"/><stop offset="0.855" stop-color="#FE7B02" stop-opacity="0.0051"/><stop offset="1" stop-color="#FE7B02" stop-opacity="0"/></radialGradient></defs>
16
+ </svg>
@@ -0,0 +1,3 @@
1
+ declare const lovableMarkUrl: string;
2
+
3
+ export default lovableMarkUrl;
package/dist/index.cjs CHANGED
@@ -7,6 +7,11 @@ const DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
7
7
  const DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
8
8
  const POPUP_CHECK_INTERVAL_MS = 500;
9
9
  const IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
10
+ const MOBILE_APP_SCHEME_UA_TOKEN = /LovableAppScheme\/([a-z0-9.+-]+)/i;
11
+ function mobileDeepLinkRedirectUri(ua) {
12
+ const scheme = MOBILE_APP_SCHEME_UA_TOKEN.exec(ua)?.[1];
13
+ return scheme ? `${scheme}://oauth-callback` : DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
14
+ }
10
15
  function startWebMessageListener(supportedOrigins) {
11
16
  let resolvePromise;
12
17
  const promise = new Promise((resolve) => {
@@ -79,7 +84,7 @@ function createAuth(config = {}) {
79
84
  const isDesktopApp = !isMobileApp && /lovable/i.test(ua);
80
85
  const state = generateState();
81
86
  let redirectUri = opts.redirect_uri ?? window.location.origin;
82
- if (isMobileApp && isInIframe) redirectUri = DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
87
+ if (isMobileApp && isInIframe) redirectUri = mobileDeepLinkRedirectUri(ua);
83
88
  else if (isDesktopApp && isInIframe) redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
84
89
  const params = new URLSearchParams({
85
90
  ...opts.extraParams,
package/dist/index.js CHANGED
@@ -6,6 +6,11 @@ const DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI = "lovable://oauth-callback";
6
6
  const DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI = "http://127.0.0.1/iframe-oauth/callback";
7
7
  const POPUP_CHECK_INTERVAL_MS = 500;
8
8
  const IFRAME_FALLBACK_TIMEOUT_MS = 12e4;
9
+ const MOBILE_APP_SCHEME_UA_TOKEN = /LovableAppScheme\/([a-z0-9.+-]+)/i;
10
+ function mobileDeepLinkRedirectUri(ua) {
11
+ const scheme = MOBILE_APP_SCHEME_UA_TOKEN.exec(ua)?.[1];
12
+ return scheme ? `${scheme}://oauth-callback` : DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
13
+ }
9
14
  function startWebMessageListener(supportedOrigins) {
10
15
  let resolvePromise;
11
16
  const promise = new Promise((resolve) => {
@@ -78,7 +83,7 @@ function createAuth(config = {}) {
78
83
  const isDesktopApp = !isMobileApp && /lovable/i.test(ua);
79
84
  const state = generateState();
80
85
  let redirectUri = opts.redirect_uri ?? window.location.origin;
81
- if (isMobileApp && isInIframe) redirectUri = DEFAULT_MOBILE_DEEP_LINK_REDIRECT_URI;
86
+ if (isMobileApp && isInIframe) redirectUri = mobileDeepLinkRedirectUri(ua);
82
87
  else if (isDesktopApp && isInIframe) redirectUri = DEFAULT_DESKTOP_LOCALHOST_REDIRECT_URI;
83
88
  const params = new URLSearchParams({
84
89
  ...opts.extraParams,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/cloud-auth-js",
3
- "version": "1.1.3-rc.9",
3
+ "version": "1.2.1",
4
4
  "description": "Lovable legacy OAuth broker JS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,11 +20,21 @@
20
20
  "types": "./dist/index.d.cts",
21
21
  "default": "./dist/index.cjs"
22
22
  }
23
+ },
24
+ "./styles.css": "./styles.css",
25
+ "./lovable-mark.svg": {
26
+ "types": "./assets/lovable-mark.svg.d.ts",
27
+ "default": "./assets/lovable-mark.svg"
23
28
  }
24
29
  },
25
30
  "type": "module",
31
+ "sideEffects": [
32
+ "styles.css"
33
+ ],
26
34
  "files": [
27
- "dist"
35
+ "assets",
36
+ "dist",
37
+ "styles.css"
28
38
  ],
29
39
  "keywords": [
30
40
  "lovable",
@@ -37,7 +47,7 @@
37
47
  "jsdom": "^26",
38
48
  "rimraf": "^5.0.0",
39
49
  "tsdown": "^0.22.5",
40
- "typescript": "^5",
50
+ "typescript": "7.0.2",
41
51
  "vitest": "^4.1.0"
42
52
  },
43
53
  "scripts": {
package/styles.css ADDED
@@ -0,0 +1,71 @@
1
+ /* Camera Plain subset for "Continue", "Sign in", and "Sign up with Lovable". */
2
+ @font-face {
3
+ font-family: "Lovable Camera";
4
+ src: url("data:font/woff2;base64,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")
5
+ format("woff2");
6
+ font-weight: 400;
7
+ font-style: normal;
8
+ }
9
+
10
+ .lovable-auth-button {
11
+ position: relative;
12
+ display: inline-flex;
13
+ min-width: 220px;
14
+ min-height: 44px;
15
+ align-items: center;
16
+ justify-content: center;
17
+ box-sizing: border-box;
18
+ padding: 10px 40px;
19
+ border: 1px solid #c5cad3;
20
+ border-radius: 8px;
21
+ appearance: none;
22
+ background: #ffffff;
23
+ color: #000000;
24
+ font-family: "Lovable Camera", ui-sans-serif, system-ui, sans-serif;
25
+ font-synthesis: none;
26
+ font-size: 16px;
27
+ font-weight: 400;
28
+ line-height: 22px;
29
+ text-align: center;
30
+ cursor: pointer;
31
+ }
32
+
33
+ .lovable-auth-button::before {
34
+ position: absolute;
35
+ inset-inline-start: 16px;
36
+ width: 16px;
37
+ height: 17px;
38
+ background: url("./assets/lovable-mark.svg") center / contain no-repeat;
39
+ content: "";
40
+ }
41
+
42
+ .lovable-auth-button:hover:not(:disabled) {
43
+ border-color: #9ca3af;
44
+ background: #f9fafb;
45
+ }
46
+
47
+ .lovable-auth-button--dark {
48
+ border-color: #4b5563;
49
+ background: #000000;
50
+ color: #ffffff;
51
+ }
52
+
53
+ .lovable-auth-button--dark:hover:not(:disabled) {
54
+ border-color: #6b7280;
55
+ background: #0a0a0a;
56
+ }
57
+
58
+ .lovable-auth-button:focus-visible {
59
+ outline: 3px solid #4b73ff;
60
+ outline-offset: 2px;
61
+ }
62
+
63
+ .lovable-auth-button:disabled {
64
+ cursor: not-allowed;
65
+ opacity: 0.55;
66
+ }
67
+
68
+ .lovable-auth-button--full-width {
69
+ width: 100%;
70
+ min-width: 0;
71
+ }