@blinkdotnew/sdk 0.18.2 → 0.18.4
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 +115 -20
- package/dist/index.d.mts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +47 -20
- package/dist/index.mjs +47 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
**The full-stack TypeScript SDK that powers Blink AI-generated apps**
|
|
7
7
|
|
|
8
|
-
Blink is an AI App
|
|
8
|
+
Blink is an AI App Builder that builds fully functional apps in seconds. This SDK (`@blinkdotnew/sdk`) is the TypeScript foundation that powers every Blink app natively, providing zero-boilerplate authentication, database operations, AI capabilities, and file storage. Works seamlessly on both client-side (React, Vue, etc.) and server-side (Node.js, Deno, Edge functions).
|
|
9
9
|
|
|
10
10
|
## 🚀 Quick Start
|
|
11
11
|
|
|
@@ -133,7 +133,7 @@ const { publicUrl } = await blink.storage.upload(
|
|
|
133
133
|
|
|
134
134
|
## 🤖 What is Blink?
|
|
135
135
|
|
|
136
|
-
**Blink is an AI App
|
|
136
|
+
**Blink is an AI App Builder** that creates fully functional applications in seconds. Simply describe what you want to build, and Blink's AI agent will:
|
|
137
137
|
|
|
138
138
|
- 🏗️ **Generate complete apps** with React + TypeScript + Vite
|
|
139
139
|
- 🔧 **Auto-install this SDK** with zero configuration
|
|
@@ -240,6 +240,9 @@ await blink.auth.sendMagicLink(email)
|
|
|
240
240
|
|
|
241
241
|
// Password management
|
|
242
242
|
await blink.auth.sendPasswordResetEmail(email)
|
|
243
|
+
await blink.auth.sendPasswordResetEmail(email, {
|
|
244
|
+
redirectUrl: 'https://myapp.com/reset-password'
|
|
245
|
+
})
|
|
243
246
|
await blink.auth.changePassword(oldPass, newPass)
|
|
244
247
|
|
|
245
248
|
// Email verification
|
|
@@ -434,6 +437,10 @@ blink.auth.setToken(jwt, persist?)
|
|
|
434
437
|
const isAuth = blink.auth.isAuthenticated()
|
|
435
438
|
|
|
436
439
|
// Password management
|
|
440
|
+
await blink.auth.sendPasswordResetEmail('user@example.com')
|
|
441
|
+
await blink.auth.sendPasswordResetEmail('user@example.com', {
|
|
442
|
+
redirectUrl: 'https://myapp.com/reset-password' // Custom reset page
|
|
443
|
+
})
|
|
437
444
|
await blink.auth.changePassword('oldPass', 'newPass')
|
|
438
445
|
await blink.auth.confirmPasswordReset(token, newPassword)
|
|
439
446
|
|
|
@@ -1841,13 +1848,24 @@ const blink = createClient({
|
|
|
1841
1848
|
})
|
|
1842
1849
|
|
|
1843
1850
|
function AuthForm() {
|
|
1851
|
+
const [mode, setMode] = useState('signin') // 'signin' | 'signup' | 'reset'
|
|
1844
1852
|
const [email, setEmail] = useState('')
|
|
1845
1853
|
const [password, setPassword] = useState('')
|
|
1854
|
+
const [message, setMessage] = useState('')
|
|
1846
1855
|
|
|
1847
1856
|
const handleEmailAuth = async () => {
|
|
1848
1857
|
try {
|
|
1849
|
-
|
|
1850
|
-
|
|
1858
|
+
if (mode === 'signin') {
|
|
1859
|
+
await blink.auth.signInWithEmail(email, password)
|
|
1860
|
+
} else if (mode === 'signup') {
|
|
1861
|
+
await blink.auth.signUp({ email, password })
|
|
1862
|
+
setMessage('Account created! Check your email to verify.')
|
|
1863
|
+
} else if (mode === 'reset') {
|
|
1864
|
+
await blink.auth.sendPasswordResetEmail(email, {
|
|
1865
|
+
redirectUrl: 'https://myapp.com/reset-password' // Your custom reset page
|
|
1866
|
+
})
|
|
1867
|
+
setMessage('Password reset email sent! Check your inbox.')
|
|
1868
|
+
}
|
|
1851
1869
|
} catch (error) {
|
|
1852
1870
|
console.error('Auth failed:', error.message)
|
|
1853
1871
|
}
|
|
@@ -1862,23 +1880,100 @@ function AuthForm() {
|
|
|
1862
1880
|
}
|
|
1863
1881
|
|
|
1864
1882
|
return (
|
|
1865
|
-
<
|
|
1866
|
-
<
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1883
|
+
<div>
|
|
1884
|
+
{message && <p style={{ color: 'green' }}>{message}</p>}
|
|
1885
|
+
|
|
1886
|
+
<form onSubmit={handleEmailAuth}>
|
|
1887
|
+
<input
|
|
1888
|
+
type="email"
|
|
1889
|
+
value={email}
|
|
1890
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
1891
|
+
placeholder="Email"
|
|
1892
|
+
/>
|
|
1893
|
+
|
|
1894
|
+
{mode !== 'reset' && (
|
|
1895
|
+
<input
|
|
1896
|
+
type="password"
|
|
1897
|
+
value={password}
|
|
1898
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
1899
|
+
placeholder="Password"
|
|
1900
|
+
/>
|
|
1901
|
+
)}
|
|
1902
|
+
|
|
1903
|
+
<button type="submit">
|
|
1904
|
+
{mode === 'signin' ? 'Sign In' : mode === 'signup' ? 'Sign Up' : 'Send Reset Email'}
|
|
1905
|
+
</button>
|
|
1906
|
+
</form>
|
|
1907
|
+
|
|
1908
|
+
{mode !== 'reset' && (
|
|
1909
|
+
<button type="button" onClick={handleSocialAuth}>
|
|
1910
|
+
Continue with Google
|
|
1911
|
+
</button>
|
|
1912
|
+
)}
|
|
1913
|
+
|
|
1914
|
+
<div>
|
|
1915
|
+
{mode === 'signin' && (
|
|
1916
|
+
<>
|
|
1917
|
+
<button onClick={() => setMode('signup')}>Create Account</button>
|
|
1918
|
+
<button onClick={() => setMode('reset')}>Forgot Password?</button>
|
|
1919
|
+
</>
|
|
1920
|
+
)}
|
|
1921
|
+
{mode === 'signup' && (
|
|
1922
|
+
<button onClick={() => setMode('signin')}>Back to Sign In</button>
|
|
1923
|
+
)}
|
|
1924
|
+
{mode === 'reset' && (
|
|
1925
|
+
<button onClick={() => setMode('signin')}>Back to Sign In</button>
|
|
1926
|
+
)}
|
|
1927
|
+
</div>
|
|
1928
|
+
</div>
|
|
1929
|
+
)
|
|
1930
|
+
}
|
|
1931
|
+
```
|
|
1932
|
+
|
|
1933
|
+
#### 🔄 Custom Reset Page Handling
|
|
1934
|
+
|
|
1935
|
+
**When users click the reset link, handle it in your app:**
|
|
1936
|
+
|
|
1937
|
+
```typescript
|
|
1938
|
+
// /reset-password page component
|
|
1939
|
+
function ResetPasswordPage() {
|
|
1940
|
+
const [token, setToken] = useState('')
|
|
1941
|
+
const [projectId, setProjectId] = useState('')
|
|
1942
|
+
const [newPassword, setNewPassword] = useState('')
|
|
1943
|
+
const [message, setMessage] = useState('')
|
|
1944
|
+
|
|
1945
|
+
useEffect(() => {
|
|
1946
|
+
// Extract token and projectId from URL params
|
|
1947
|
+
const params = new URLSearchParams(window.location.search)
|
|
1948
|
+
setToken(params.get('token') || '')
|
|
1949
|
+
setProjectId(params.get('projectId') || '')
|
|
1950
|
+
}, [])
|
|
1951
|
+
|
|
1952
|
+
const handleReset = async (e) => {
|
|
1953
|
+
e.preventDefault()
|
|
1954
|
+
|
|
1955
|
+
try {
|
|
1956
|
+
await blink.auth.confirmPasswordReset(token, newPassword)
|
|
1957
|
+
setMessage('Password reset successfully! You can now sign in.')
|
|
1958
|
+
} catch (error) {
|
|
1959
|
+
console.error('Reset failed:', error.message)
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
if (!token) return <div>Invalid reset link</div>
|
|
1964
|
+
|
|
1965
|
+
return (
|
|
1966
|
+
<form onSubmit={handleReset}>
|
|
1967
|
+
<h1>Set New Password</h1>
|
|
1968
|
+
<input
|
|
1969
|
+
type="password"
|
|
1970
|
+
value={newPassword}
|
|
1971
|
+
onChange={(e) => setNewPassword(e.target.value)}
|
|
1972
|
+
placeholder="Enter new password"
|
|
1973
|
+
minLength={8}
|
|
1877
1974
|
/>
|
|
1878
|
-
<button type="submit">
|
|
1879
|
-
<
|
|
1880
|
-
Continue with Google
|
|
1881
|
-
</button>
|
|
1975
|
+
<button type="submit">Reset Password</button>
|
|
1976
|
+
{message && <p style={{ color: 'green' }}>{message}</p>}
|
|
1882
1977
|
</form>
|
|
1883
1978
|
)
|
|
1884
1979
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -826,6 +826,14 @@ declare class BlinkAuth {
|
|
|
826
826
|
private initializationPromise;
|
|
827
827
|
private isInitialized;
|
|
828
828
|
constructor(config: BlinkClientConfig);
|
|
829
|
+
/**
|
|
830
|
+
* Generate project-scoped storage key
|
|
831
|
+
*/
|
|
832
|
+
private getStorageKey;
|
|
833
|
+
/**
|
|
834
|
+
* Migrate existing global tokens to project-scoped storage
|
|
835
|
+
*/
|
|
836
|
+
private migrateExistingTokens;
|
|
829
837
|
/**
|
|
830
838
|
* Wait for authentication initialization to complete
|
|
831
839
|
*/
|
|
@@ -914,7 +922,9 @@ declare class BlinkAuth {
|
|
|
914
922
|
/**
|
|
915
923
|
* Send password reset email (using Blink default email service)
|
|
916
924
|
*/
|
|
917
|
-
sendPasswordResetEmail(email: string
|
|
925
|
+
sendPasswordResetEmail(email: string, options?: {
|
|
926
|
+
redirectUrl?: string;
|
|
927
|
+
}): Promise<void>;
|
|
918
928
|
/**
|
|
919
929
|
* Confirm password reset with token
|
|
920
930
|
*/
|
|
@@ -1236,6 +1246,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
|
|
|
1236
1246
|
private utmParams;
|
|
1237
1247
|
private persistedAttribution;
|
|
1238
1248
|
constructor(httpClient: HttpClient, projectId: string);
|
|
1249
|
+
/**
|
|
1250
|
+
* Generate project-scoped storage key for analytics
|
|
1251
|
+
*/
|
|
1252
|
+
private getStorageKey;
|
|
1239
1253
|
/**
|
|
1240
1254
|
* Log a custom analytics event
|
|
1241
1255
|
*/
|
|
@@ -1475,7 +1489,7 @@ declare class BlinkAIImpl implements BlinkAI {
|
|
|
1475
1489
|
* // With options
|
|
1476
1490
|
* const { text, usage } = await blink.ai.generateText({
|
|
1477
1491
|
* prompt: "Summarize this article",
|
|
1478
|
-
* model: "gpt-
|
|
1492
|
+
* model: "gpt-4.1-mini",
|
|
1479
1493
|
* maxTokens: 150,
|
|
1480
1494
|
* temperature: 0.7
|
|
1481
1495
|
* });
|
|
@@ -1483,7 +1497,7 @@ declare class BlinkAIImpl implements BlinkAI {
|
|
|
1483
1497
|
* // With web search (OpenAI models only)
|
|
1484
1498
|
* const { text, sources } = await blink.ai.generateText({
|
|
1485
1499
|
* prompt: "What are the latest developments in AI?",
|
|
1486
|
-
* model: "gpt-
|
|
1500
|
+
* model: "gpt-4.1-mini",
|
|
1487
1501
|
* search: true // Enables web search
|
|
1488
1502
|
* });
|
|
1489
1503
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -826,6 +826,14 @@ declare class BlinkAuth {
|
|
|
826
826
|
private initializationPromise;
|
|
827
827
|
private isInitialized;
|
|
828
828
|
constructor(config: BlinkClientConfig);
|
|
829
|
+
/**
|
|
830
|
+
* Generate project-scoped storage key
|
|
831
|
+
*/
|
|
832
|
+
private getStorageKey;
|
|
833
|
+
/**
|
|
834
|
+
* Migrate existing global tokens to project-scoped storage
|
|
835
|
+
*/
|
|
836
|
+
private migrateExistingTokens;
|
|
829
837
|
/**
|
|
830
838
|
* Wait for authentication initialization to complete
|
|
831
839
|
*/
|
|
@@ -914,7 +922,9 @@ declare class BlinkAuth {
|
|
|
914
922
|
/**
|
|
915
923
|
* Send password reset email (using Blink default email service)
|
|
916
924
|
*/
|
|
917
|
-
sendPasswordResetEmail(email: string
|
|
925
|
+
sendPasswordResetEmail(email: string, options?: {
|
|
926
|
+
redirectUrl?: string;
|
|
927
|
+
}): Promise<void>;
|
|
918
928
|
/**
|
|
919
929
|
* Confirm password reset with token
|
|
920
930
|
*/
|
|
@@ -1236,6 +1246,10 @@ declare class BlinkAnalyticsImpl implements BlinkAnalytics {
|
|
|
1236
1246
|
private utmParams;
|
|
1237
1247
|
private persistedAttribution;
|
|
1238
1248
|
constructor(httpClient: HttpClient, projectId: string);
|
|
1249
|
+
/**
|
|
1250
|
+
* Generate project-scoped storage key for analytics
|
|
1251
|
+
*/
|
|
1252
|
+
private getStorageKey;
|
|
1239
1253
|
/**
|
|
1240
1254
|
* Log a custom analytics event
|
|
1241
1255
|
*/
|
|
@@ -1475,7 +1489,7 @@ declare class BlinkAIImpl implements BlinkAI {
|
|
|
1475
1489
|
* // With options
|
|
1476
1490
|
* const { text, usage } = await blink.ai.generateText({
|
|
1477
1491
|
* prompt: "Summarize this article",
|
|
1478
|
-
* model: "gpt-
|
|
1492
|
+
* model: "gpt-4.1-mini",
|
|
1479
1493
|
* maxTokens: 150,
|
|
1480
1494
|
* temperature: 0.7
|
|
1481
1495
|
* });
|
|
@@ -1483,7 +1497,7 @@ declare class BlinkAIImpl implements BlinkAI {
|
|
|
1483
1497
|
* // With web search (OpenAI models only)
|
|
1484
1498
|
* const { text, sources } = await blink.ai.generateText({
|
|
1485
1499
|
* prompt: "What are the latest developments in AI?",
|
|
1486
|
-
* model: "gpt-
|
|
1500
|
+
* model: "gpt-4.1-mini",
|
|
1487
1501
|
* search: true // Enables web search
|
|
1488
1502
|
* });
|
|
1489
1503
|
*
|
package/dist/index.js
CHANGED
|
@@ -916,6 +916,9 @@ var BlinkAuth = class {
|
|
|
916
916
|
isInitialized = false;
|
|
917
917
|
constructor(config) {
|
|
918
918
|
this.config = config;
|
|
919
|
+
if (!config.projectId) {
|
|
920
|
+
throw new Error("projectId is required for authentication");
|
|
921
|
+
}
|
|
919
922
|
this.authConfig = {
|
|
920
923
|
mode: "managed",
|
|
921
924
|
// Default mode
|
|
@@ -946,6 +949,25 @@ var BlinkAuth = class {
|
|
|
946
949
|
this.isInitialized = true;
|
|
947
950
|
}
|
|
948
951
|
}
|
|
952
|
+
/**
|
|
953
|
+
* Generate project-scoped storage key
|
|
954
|
+
*/
|
|
955
|
+
getStorageKey(suffix) {
|
|
956
|
+
return `blink_${suffix}_${this.config.projectId}`;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Migrate existing global tokens to project-scoped storage
|
|
960
|
+
*/
|
|
961
|
+
migrateExistingTokens() {
|
|
962
|
+
if (typeof window === "undefined") return;
|
|
963
|
+
const oldTokens = localStorage.getItem("blink_tokens");
|
|
964
|
+
const projectKey = this.getStorageKey("tokens");
|
|
965
|
+
if (oldTokens && !localStorage.getItem(projectKey)) {
|
|
966
|
+
localStorage.setItem(projectKey, oldTokens);
|
|
967
|
+
localStorage.removeItem("blink_tokens");
|
|
968
|
+
console.log(`\u2705 Migrated tokens to project scope: ${this.config.projectId}`);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
949
971
|
/**
|
|
950
972
|
* Wait for authentication initialization to complete
|
|
951
973
|
*/
|
|
@@ -996,6 +1018,7 @@ var BlinkAuth = class {
|
|
|
996
1018
|
console.log("\u{1F680} Initializing Blink Auth...");
|
|
997
1019
|
this.setLoading(true);
|
|
998
1020
|
try {
|
|
1021
|
+
this.migrateExistingTokens();
|
|
999
1022
|
if (this.isIframe) {
|
|
1000
1023
|
console.log("\u{1F50D} Detected iframe environment, waiting for parent tokens...");
|
|
1001
1024
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -1501,7 +1524,7 @@ var BlinkAuth = class {
|
|
|
1501
1524
|
/**
|
|
1502
1525
|
* Send password reset email (using Blink default email service)
|
|
1503
1526
|
*/
|
|
1504
|
-
async sendPasswordResetEmail(email) {
|
|
1527
|
+
async sendPasswordResetEmail(email, options) {
|
|
1505
1528
|
try {
|
|
1506
1529
|
const response = await fetch(`${this.authUrl}/api/auth/password/reset`, {
|
|
1507
1530
|
method: "POST",
|
|
@@ -1510,7 +1533,8 @@ var BlinkAuth = class {
|
|
|
1510
1533
|
},
|
|
1511
1534
|
body: JSON.stringify({
|
|
1512
1535
|
email,
|
|
1513
|
-
projectId: this.config.projectId
|
|
1536
|
+
projectId: this.config.projectId,
|
|
1537
|
+
redirectUrl: options?.redirectUrl
|
|
1514
1538
|
})
|
|
1515
1539
|
});
|
|
1516
1540
|
if (!response.ok) {
|
|
@@ -2067,7 +2091,7 @@ var BlinkAuth = class {
|
|
|
2067
2091
|
});
|
|
2068
2092
|
if (persist && typeof window !== "undefined") {
|
|
2069
2093
|
try {
|
|
2070
|
-
localStorage.setItem("
|
|
2094
|
+
localStorage.setItem(this.getStorageKey("tokens"), JSON.stringify(tokensWithTimestamp));
|
|
2071
2095
|
console.log("\u{1F4BE} Tokens persisted to localStorage");
|
|
2072
2096
|
} catch (error) {
|
|
2073
2097
|
console.log("\u{1F4A5} Error persisting tokens to localStorage:", error);
|
|
@@ -2118,7 +2142,7 @@ var BlinkAuth = class {
|
|
|
2118
2142
|
clearTokens() {
|
|
2119
2143
|
if (typeof window !== "undefined") {
|
|
2120
2144
|
try {
|
|
2121
|
-
localStorage.removeItem("
|
|
2145
|
+
localStorage.removeItem(this.getStorageKey("tokens"));
|
|
2122
2146
|
} catch (error) {
|
|
2123
2147
|
console.log("\u{1F4A5} Error clearing tokens from localStorage:", error);
|
|
2124
2148
|
}
|
|
@@ -2136,7 +2160,7 @@ var BlinkAuth = class {
|
|
|
2136
2160
|
return this.parentWindowTokens;
|
|
2137
2161
|
}
|
|
2138
2162
|
try {
|
|
2139
|
-
const stored = localStorage.getItem("
|
|
2163
|
+
const stored = localStorage.getItem(this.getStorageKey("tokens"));
|
|
2140
2164
|
console.log("\u{1F50D} Checking localStorage for tokens:", {
|
|
2141
2165
|
hasStoredData: !!stored,
|
|
2142
2166
|
storedLength: stored?.length || 0,
|
|
@@ -2306,7 +2330,7 @@ var BlinkAuth = class {
|
|
|
2306
2330
|
setupCrossTabSync() {
|
|
2307
2331
|
if (typeof window === "undefined") return;
|
|
2308
2332
|
window.addEventListener("storage", (e) => {
|
|
2309
|
-
if (e.key === "
|
|
2333
|
+
if (e.key === this.getStorageKey("tokens")) {
|
|
2310
2334
|
const newTokens = e.newValue ? JSON.parse(e.newValue) : null;
|
|
2311
2335
|
if (newTokens && newTokens !== this.authState.tokens) {
|
|
2312
2336
|
this.setTokens(newTokens, false).catch((error) => {
|
|
@@ -3053,7 +3077,7 @@ var BlinkAIImpl = class {
|
|
|
3053
3077
|
* // With options
|
|
3054
3078
|
* const { text, usage } = await blink.ai.generateText({
|
|
3055
3079
|
* prompt: "Summarize this article",
|
|
3056
|
-
* model: "gpt-
|
|
3080
|
+
* model: "gpt-4.1-mini",
|
|
3057
3081
|
* maxTokens: 150,
|
|
3058
3082
|
* temperature: 0.7
|
|
3059
3083
|
* });
|
|
@@ -3061,7 +3085,7 @@ var BlinkAIImpl = class {
|
|
|
3061
3085
|
* // With web search (OpenAI models only)
|
|
3062
3086
|
* const { text, sources } = await blink.ai.generateText({
|
|
3063
3087
|
* prompt: "What are the latest developments in AI?",
|
|
3064
|
-
* model: "gpt-
|
|
3088
|
+
* model: "gpt-4.1-mini",
|
|
3065
3089
|
* search: true // Enables web search
|
|
3066
3090
|
* });
|
|
3067
3091
|
*
|
|
@@ -4455,9 +4479,6 @@ var SESSION_DURATION = 30 * 60 * 1e3;
|
|
|
4455
4479
|
var MAX_BATCH_SIZE = 10;
|
|
4456
4480
|
var BATCH_TIMEOUT = 3e3;
|
|
4457
4481
|
var MAX_STRING_LENGTH = 256;
|
|
4458
|
-
var STORAGE_KEY_QUEUE = "blinkAnalyticsQueue";
|
|
4459
|
-
var STORAGE_KEY_SESSION = "blinkAnalyticsSession";
|
|
4460
|
-
var STORAGE_KEY_ATTRIBUTION = "blinkAnalyticsAttribution";
|
|
4461
4482
|
var BlinkAnalyticsImpl = class {
|
|
4462
4483
|
httpClient;
|
|
4463
4484
|
projectId;
|
|
@@ -4486,6 +4507,12 @@ var BlinkAnalyticsImpl = class {
|
|
|
4486
4507
|
this.setupRouteChangeListener();
|
|
4487
4508
|
this.setupUnloadListener();
|
|
4488
4509
|
}
|
|
4510
|
+
/**
|
|
4511
|
+
* Generate project-scoped storage key for analytics
|
|
4512
|
+
*/
|
|
4513
|
+
getStorageKey(suffix) {
|
|
4514
|
+
return `blinkAnalytics${suffix}_${this.projectId}`;
|
|
4515
|
+
}
|
|
4489
4516
|
/**
|
|
4490
4517
|
* Log a custom analytics event
|
|
4491
4518
|
*/
|
|
@@ -4542,7 +4569,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4542
4569
|
clearAttribution() {
|
|
4543
4570
|
this.persistedAttribution = {};
|
|
4544
4571
|
try {
|
|
4545
|
-
localStorage.removeItem(
|
|
4572
|
+
localStorage.removeItem(this.getStorageKey("Attribution"));
|
|
4546
4573
|
} catch {
|
|
4547
4574
|
}
|
|
4548
4575
|
}
|
|
@@ -4618,7 +4645,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4618
4645
|
}
|
|
4619
4646
|
getOrCreateSessionId() {
|
|
4620
4647
|
try {
|
|
4621
|
-
const stored = localStorage.getItem(
|
|
4648
|
+
const stored = localStorage.getItem(this.getStorageKey("Session"));
|
|
4622
4649
|
if (stored) {
|
|
4623
4650
|
const session = JSON.parse(stored);
|
|
4624
4651
|
const now = Date.now();
|
|
@@ -4626,7 +4653,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4626
4653
|
return this.createNewSession();
|
|
4627
4654
|
}
|
|
4628
4655
|
session.lastActivityAt = now;
|
|
4629
|
-
localStorage.setItem(
|
|
4656
|
+
localStorage.setItem(this.getStorageKey("Session"), JSON.stringify(session));
|
|
4630
4657
|
return session.id;
|
|
4631
4658
|
}
|
|
4632
4659
|
return this.createNewSession();
|
|
@@ -4643,14 +4670,14 @@ var BlinkAnalyticsImpl = class {
|
|
|
4643
4670
|
lastActivityAt: now
|
|
4644
4671
|
};
|
|
4645
4672
|
try {
|
|
4646
|
-
localStorage.setItem(
|
|
4673
|
+
localStorage.setItem(this.getStorageKey("Session"), JSON.stringify(session));
|
|
4647
4674
|
} catch {
|
|
4648
4675
|
}
|
|
4649
4676
|
return session.id;
|
|
4650
4677
|
}
|
|
4651
4678
|
loadQueue() {
|
|
4652
4679
|
try {
|
|
4653
|
-
const stored = localStorage.getItem(
|
|
4680
|
+
const stored = localStorage.getItem(this.getStorageKey("Queue"));
|
|
4654
4681
|
if (stored) {
|
|
4655
4682
|
this.queue = JSON.parse(stored);
|
|
4656
4683
|
if (this.queue.length > 0) {
|
|
@@ -4664,9 +4691,9 @@ var BlinkAnalyticsImpl = class {
|
|
|
4664
4691
|
persistQueue() {
|
|
4665
4692
|
try {
|
|
4666
4693
|
if (this.queue.length === 0) {
|
|
4667
|
-
localStorage.removeItem(
|
|
4694
|
+
localStorage.removeItem(this.getStorageKey("Queue"));
|
|
4668
4695
|
} else {
|
|
4669
|
-
localStorage.setItem(
|
|
4696
|
+
localStorage.setItem(this.getStorageKey("Queue"), JSON.stringify(this.queue));
|
|
4670
4697
|
}
|
|
4671
4698
|
} catch {
|
|
4672
4699
|
}
|
|
@@ -4734,7 +4761,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4734
4761
|
}
|
|
4735
4762
|
loadPersistedAttribution() {
|
|
4736
4763
|
try {
|
|
4737
|
-
const stored = localStorage.getItem(
|
|
4764
|
+
const stored = localStorage.getItem(this.getStorageKey("Attribution"));
|
|
4738
4765
|
if (stored) {
|
|
4739
4766
|
this.persistedAttribution = JSON.parse(stored);
|
|
4740
4767
|
}
|
|
@@ -4750,7 +4777,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4750
4777
|
Object.entries(this.utmParams).filter(([_, v]) => v !== null)
|
|
4751
4778
|
)
|
|
4752
4779
|
};
|
|
4753
|
-
localStorage.setItem(
|
|
4780
|
+
localStorage.setItem(this.getStorageKey("Attribution"), JSON.stringify(attribution));
|
|
4754
4781
|
this.persistedAttribution = attribution;
|
|
4755
4782
|
} catch {
|
|
4756
4783
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -914,6 +914,9 @@ var BlinkAuth = class {
|
|
|
914
914
|
isInitialized = false;
|
|
915
915
|
constructor(config) {
|
|
916
916
|
this.config = config;
|
|
917
|
+
if (!config.projectId) {
|
|
918
|
+
throw new Error("projectId is required for authentication");
|
|
919
|
+
}
|
|
917
920
|
this.authConfig = {
|
|
918
921
|
mode: "managed",
|
|
919
922
|
// Default mode
|
|
@@ -944,6 +947,25 @@ var BlinkAuth = class {
|
|
|
944
947
|
this.isInitialized = true;
|
|
945
948
|
}
|
|
946
949
|
}
|
|
950
|
+
/**
|
|
951
|
+
* Generate project-scoped storage key
|
|
952
|
+
*/
|
|
953
|
+
getStorageKey(suffix) {
|
|
954
|
+
return `blink_${suffix}_${this.config.projectId}`;
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Migrate existing global tokens to project-scoped storage
|
|
958
|
+
*/
|
|
959
|
+
migrateExistingTokens() {
|
|
960
|
+
if (typeof window === "undefined") return;
|
|
961
|
+
const oldTokens = localStorage.getItem("blink_tokens");
|
|
962
|
+
const projectKey = this.getStorageKey("tokens");
|
|
963
|
+
if (oldTokens && !localStorage.getItem(projectKey)) {
|
|
964
|
+
localStorage.setItem(projectKey, oldTokens);
|
|
965
|
+
localStorage.removeItem("blink_tokens");
|
|
966
|
+
console.log(`\u2705 Migrated tokens to project scope: ${this.config.projectId}`);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
947
969
|
/**
|
|
948
970
|
* Wait for authentication initialization to complete
|
|
949
971
|
*/
|
|
@@ -994,6 +1016,7 @@ var BlinkAuth = class {
|
|
|
994
1016
|
console.log("\u{1F680} Initializing Blink Auth...");
|
|
995
1017
|
this.setLoading(true);
|
|
996
1018
|
try {
|
|
1019
|
+
this.migrateExistingTokens();
|
|
997
1020
|
if (this.isIframe) {
|
|
998
1021
|
console.log("\u{1F50D} Detected iframe environment, waiting for parent tokens...");
|
|
999
1022
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -1499,7 +1522,7 @@ var BlinkAuth = class {
|
|
|
1499
1522
|
/**
|
|
1500
1523
|
* Send password reset email (using Blink default email service)
|
|
1501
1524
|
*/
|
|
1502
|
-
async sendPasswordResetEmail(email) {
|
|
1525
|
+
async sendPasswordResetEmail(email, options) {
|
|
1503
1526
|
try {
|
|
1504
1527
|
const response = await fetch(`${this.authUrl}/api/auth/password/reset`, {
|
|
1505
1528
|
method: "POST",
|
|
@@ -1508,7 +1531,8 @@ var BlinkAuth = class {
|
|
|
1508
1531
|
},
|
|
1509
1532
|
body: JSON.stringify({
|
|
1510
1533
|
email,
|
|
1511
|
-
projectId: this.config.projectId
|
|
1534
|
+
projectId: this.config.projectId,
|
|
1535
|
+
redirectUrl: options?.redirectUrl
|
|
1512
1536
|
})
|
|
1513
1537
|
});
|
|
1514
1538
|
if (!response.ok) {
|
|
@@ -2065,7 +2089,7 @@ var BlinkAuth = class {
|
|
|
2065
2089
|
});
|
|
2066
2090
|
if (persist && typeof window !== "undefined") {
|
|
2067
2091
|
try {
|
|
2068
|
-
localStorage.setItem("
|
|
2092
|
+
localStorage.setItem(this.getStorageKey("tokens"), JSON.stringify(tokensWithTimestamp));
|
|
2069
2093
|
console.log("\u{1F4BE} Tokens persisted to localStorage");
|
|
2070
2094
|
} catch (error) {
|
|
2071
2095
|
console.log("\u{1F4A5} Error persisting tokens to localStorage:", error);
|
|
@@ -2116,7 +2140,7 @@ var BlinkAuth = class {
|
|
|
2116
2140
|
clearTokens() {
|
|
2117
2141
|
if (typeof window !== "undefined") {
|
|
2118
2142
|
try {
|
|
2119
|
-
localStorage.removeItem("
|
|
2143
|
+
localStorage.removeItem(this.getStorageKey("tokens"));
|
|
2120
2144
|
} catch (error) {
|
|
2121
2145
|
console.log("\u{1F4A5} Error clearing tokens from localStorage:", error);
|
|
2122
2146
|
}
|
|
@@ -2134,7 +2158,7 @@ var BlinkAuth = class {
|
|
|
2134
2158
|
return this.parentWindowTokens;
|
|
2135
2159
|
}
|
|
2136
2160
|
try {
|
|
2137
|
-
const stored = localStorage.getItem("
|
|
2161
|
+
const stored = localStorage.getItem(this.getStorageKey("tokens"));
|
|
2138
2162
|
console.log("\u{1F50D} Checking localStorage for tokens:", {
|
|
2139
2163
|
hasStoredData: !!stored,
|
|
2140
2164
|
storedLength: stored?.length || 0,
|
|
@@ -2304,7 +2328,7 @@ var BlinkAuth = class {
|
|
|
2304
2328
|
setupCrossTabSync() {
|
|
2305
2329
|
if (typeof window === "undefined") return;
|
|
2306
2330
|
window.addEventListener("storage", (e) => {
|
|
2307
|
-
if (e.key === "
|
|
2331
|
+
if (e.key === this.getStorageKey("tokens")) {
|
|
2308
2332
|
const newTokens = e.newValue ? JSON.parse(e.newValue) : null;
|
|
2309
2333
|
if (newTokens && newTokens !== this.authState.tokens) {
|
|
2310
2334
|
this.setTokens(newTokens, false).catch((error) => {
|
|
@@ -3051,7 +3075,7 @@ var BlinkAIImpl = class {
|
|
|
3051
3075
|
* // With options
|
|
3052
3076
|
* const { text, usage } = await blink.ai.generateText({
|
|
3053
3077
|
* prompt: "Summarize this article",
|
|
3054
|
-
* model: "gpt-
|
|
3078
|
+
* model: "gpt-4.1-mini",
|
|
3055
3079
|
* maxTokens: 150,
|
|
3056
3080
|
* temperature: 0.7
|
|
3057
3081
|
* });
|
|
@@ -3059,7 +3083,7 @@ var BlinkAIImpl = class {
|
|
|
3059
3083
|
* // With web search (OpenAI models only)
|
|
3060
3084
|
* const { text, sources } = await blink.ai.generateText({
|
|
3061
3085
|
* prompt: "What are the latest developments in AI?",
|
|
3062
|
-
* model: "gpt-
|
|
3086
|
+
* model: "gpt-4.1-mini",
|
|
3063
3087
|
* search: true // Enables web search
|
|
3064
3088
|
* });
|
|
3065
3089
|
*
|
|
@@ -4453,9 +4477,6 @@ var SESSION_DURATION = 30 * 60 * 1e3;
|
|
|
4453
4477
|
var MAX_BATCH_SIZE = 10;
|
|
4454
4478
|
var BATCH_TIMEOUT = 3e3;
|
|
4455
4479
|
var MAX_STRING_LENGTH = 256;
|
|
4456
|
-
var STORAGE_KEY_QUEUE = "blinkAnalyticsQueue";
|
|
4457
|
-
var STORAGE_KEY_SESSION = "blinkAnalyticsSession";
|
|
4458
|
-
var STORAGE_KEY_ATTRIBUTION = "blinkAnalyticsAttribution";
|
|
4459
4480
|
var BlinkAnalyticsImpl = class {
|
|
4460
4481
|
httpClient;
|
|
4461
4482
|
projectId;
|
|
@@ -4484,6 +4505,12 @@ var BlinkAnalyticsImpl = class {
|
|
|
4484
4505
|
this.setupRouteChangeListener();
|
|
4485
4506
|
this.setupUnloadListener();
|
|
4486
4507
|
}
|
|
4508
|
+
/**
|
|
4509
|
+
* Generate project-scoped storage key for analytics
|
|
4510
|
+
*/
|
|
4511
|
+
getStorageKey(suffix) {
|
|
4512
|
+
return `blinkAnalytics${suffix}_${this.projectId}`;
|
|
4513
|
+
}
|
|
4487
4514
|
/**
|
|
4488
4515
|
* Log a custom analytics event
|
|
4489
4516
|
*/
|
|
@@ -4540,7 +4567,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4540
4567
|
clearAttribution() {
|
|
4541
4568
|
this.persistedAttribution = {};
|
|
4542
4569
|
try {
|
|
4543
|
-
localStorage.removeItem(
|
|
4570
|
+
localStorage.removeItem(this.getStorageKey("Attribution"));
|
|
4544
4571
|
} catch {
|
|
4545
4572
|
}
|
|
4546
4573
|
}
|
|
@@ -4616,7 +4643,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4616
4643
|
}
|
|
4617
4644
|
getOrCreateSessionId() {
|
|
4618
4645
|
try {
|
|
4619
|
-
const stored = localStorage.getItem(
|
|
4646
|
+
const stored = localStorage.getItem(this.getStorageKey("Session"));
|
|
4620
4647
|
if (stored) {
|
|
4621
4648
|
const session = JSON.parse(stored);
|
|
4622
4649
|
const now = Date.now();
|
|
@@ -4624,7 +4651,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4624
4651
|
return this.createNewSession();
|
|
4625
4652
|
}
|
|
4626
4653
|
session.lastActivityAt = now;
|
|
4627
|
-
localStorage.setItem(
|
|
4654
|
+
localStorage.setItem(this.getStorageKey("Session"), JSON.stringify(session));
|
|
4628
4655
|
return session.id;
|
|
4629
4656
|
}
|
|
4630
4657
|
return this.createNewSession();
|
|
@@ -4641,14 +4668,14 @@ var BlinkAnalyticsImpl = class {
|
|
|
4641
4668
|
lastActivityAt: now
|
|
4642
4669
|
};
|
|
4643
4670
|
try {
|
|
4644
|
-
localStorage.setItem(
|
|
4671
|
+
localStorage.setItem(this.getStorageKey("Session"), JSON.stringify(session));
|
|
4645
4672
|
} catch {
|
|
4646
4673
|
}
|
|
4647
4674
|
return session.id;
|
|
4648
4675
|
}
|
|
4649
4676
|
loadQueue() {
|
|
4650
4677
|
try {
|
|
4651
|
-
const stored = localStorage.getItem(
|
|
4678
|
+
const stored = localStorage.getItem(this.getStorageKey("Queue"));
|
|
4652
4679
|
if (stored) {
|
|
4653
4680
|
this.queue = JSON.parse(stored);
|
|
4654
4681
|
if (this.queue.length > 0) {
|
|
@@ -4662,9 +4689,9 @@ var BlinkAnalyticsImpl = class {
|
|
|
4662
4689
|
persistQueue() {
|
|
4663
4690
|
try {
|
|
4664
4691
|
if (this.queue.length === 0) {
|
|
4665
|
-
localStorage.removeItem(
|
|
4692
|
+
localStorage.removeItem(this.getStorageKey("Queue"));
|
|
4666
4693
|
} else {
|
|
4667
|
-
localStorage.setItem(
|
|
4694
|
+
localStorage.setItem(this.getStorageKey("Queue"), JSON.stringify(this.queue));
|
|
4668
4695
|
}
|
|
4669
4696
|
} catch {
|
|
4670
4697
|
}
|
|
@@ -4732,7 +4759,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4732
4759
|
}
|
|
4733
4760
|
loadPersistedAttribution() {
|
|
4734
4761
|
try {
|
|
4735
|
-
const stored = localStorage.getItem(
|
|
4762
|
+
const stored = localStorage.getItem(this.getStorageKey("Attribution"));
|
|
4736
4763
|
if (stored) {
|
|
4737
4764
|
this.persistedAttribution = JSON.parse(stored);
|
|
4738
4765
|
}
|
|
@@ -4748,7 +4775,7 @@ var BlinkAnalyticsImpl = class {
|
|
|
4748
4775
|
Object.entries(this.utmParams).filter(([_, v]) => v !== null)
|
|
4749
4776
|
)
|
|
4750
4777
|
};
|
|
4751
|
-
localStorage.setItem(
|
|
4778
|
+
localStorage.setItem(this.getStorageKey("Attribution"), JSON.stringify(attribution));
|
|
4752
4779
|
this.persistedAttribution = attribution;
|
|
4753
4780
|
} catch {
|
|
4754
4781
|
}
|
package/package.json
CHANGED