fetchguard 2.1.2 → 2.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 +52 -23
- package/dist/index.d.ts +3 -617
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/worker-DBL8XAZJ.d.ts +643 -0
- package/dist/worker.d.ts +2 -2
- package/dist/worker.js +34 -0
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -516,67 +516,96 @@ await api.login(...) // has X-Client-Version, X-Platform, Accept-Langua
|
|
|
516
516
|
2. `provider.headers` (auth requests only)
|
|
517
517
|
3. Per-request headers (highest priority)
|
|
518
518
|
|
|
519
|
-
### Advanced: Custom Providers
|
|
519
|
+
### Advanced: Custom Providers with workerFactory
|
|
520
520
|
|
|
521
|
-
For complex auth flows,
|
|
521
|
+
For complex auth flows with custom parsers or strategies, use `workerFactory` to create a custom worker:
|
|
522
|
+
|
|
523
|
+
**Step 1: Create custom worker file (my-worker.ts)**
|
|
522
524
|
|
|
523
525
|
```ts
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
import {
|
|
526
|
+
// my-worker.ts
|
|
527
|
+
// IMPORTANT: Import from 'fetchguard/worker' to ensure same registry instance!
|
|
528
|
+
import {
|
|
529
|
+
registerProvider,
|
|
530
|
+
createProvider,
|
|
531
|
+
createIndexedDBStorage
|
|
532
|
+
} from 'fetchguard/worker'
|
|
527
533
|
|
|
528
|
-
//
|
|
529
|
-
|
|
534
|
+
// Register custom provider INSIDE the worker
|
|
535
|
+
registerProvider('my-custom-auth', createProvider({
|
|
530
536
|
refreshStorage: createIndexedDBStorage('MyApp', 'refreshToken'),
|
|
531
537
|
parser: {
|
|
532
538
|
async parse(response: Response) {
|
|
533
539
|
const data = await response.json()
|
|
540
|
+
// Custom response format
|
|
534
541
|
return {
|
|
535
|
-
token: data.accessToken,
|
|
536
|
-
refreshToken: data.refreshToken,
|
|
537
|
-
expiresAt: data.
|
|
538
|
-
user: data.
|
|
542
|
+
token: data.result.accessToken,
|
|
543
|
+
refreshToken: data.result.refreshToken,
|
|
544
|
+
expiresAt: data.result.exp * 1000,
|
|
545
|
+
user: data.result.profile
|
|
539
546
|
}
|
|
540
547
|
}
|
|
541
548
|
},
|
|
542
549
|
strategy: {
|
|
543
|
-
async
|
|
544
|
-
|
|
550
|
+
async refresh(refreshToken: string | null) {
|
|
551
|
+
return fetch('https://api.example.com/auth/refresh', {
|
|
545
552
|
method: 'POST',
|
|
546
553
|
headers: { 'Content-Type': 'application/json' },
|
|
547
554
|
body: JSON.stringify({ refreshToken })
|
|
548
555
|
})
|
|
549
|
-
return res
|
|
550
556
|
},
|
|
551
557
|
async login(payload: unknown) {
|
|
552
|
-
|
|
558
|
+
return fetch('https://api.example.com/auth/login', {
|
|
553
559
|
method: 'POST',
|
|
554
560
|
headers: { 'Content-Type': 'application/json' },
|
|
555
561
|
body: JSON.stringify(payload)
|
|
556
562
|
})
|
|
557
|
-
return res
|
|
558
563
|
},
|
|
559
564
|
async logout(payload?: unknown) {
|
|
560
|
-
|
|
565
|
+
return fetch('https://api.example.com/auth/logout', {
|
|
561
566
|
method: 'POST',
|
|
562
567
|
headers: { 'Content-Type': 'application/json' },
|
|
563
568
|
body: JSON.stringify(payload || {})
|
|
564
569
|
})
|
|
565
|
-
|
|
570
|
+
},
|
|
571
|
+
async exchangeToken(accessToken: string, url: string, options?: { method?: string; payload?: unknown; headers?: Record<string, string> }) {
|
|
572
|
+
return fetch(url, {
|
|
573
|
+
method: options?.method || 'POST',
|
|
574
|
+
headers: {
|
|
575
|
+
'Content-Type': 'application/json',
|
|
576
|
+
...options?.headers,
|
|
577
|
+
'Authorization': `Bearer ${accessToken}`
|
|
578
|
+
},
|
|
579
|
+
body: options?.payload ? JSON.stringify(options.payload) : undefined
|
|
580
|
+
})
|
|
566
581
|
}
|
|
567
582
|
}
|
|
568
|
-
})
|
|
583
|
+
}))
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Step 2: Use workerFactory in main thread**
|
|
569
587
|
|
|
570
|
-
|
|
571
|
-
|
|
588
|
+
```ts
|
|
589
|
+
// main.ts
|
|
590
|
+
import { createClient } from 'fetchguard'
|
|
572
591
|
|
|
573
|
-
// Use registered provider
|
|
574
592
|
const api = createClient({
|
|
575
|
-
provider: 'my-custom-auth', // Reference by name
|
|
593
|
+
provider: 'my-custom-auth', // Reference registered provider by name
|
|
594
|
+
workerFactory: () => new Worker(
|
|
595
|
+
new URL('./my-worker.ts', import.meta.url),
|
|
596
|
+
{ type: 'module' }
|
|
597
|
+
),
|
|
576
598
|
allowedDomains: ['api.example.com']
|
|
577
599
|
})
|
|
578
600
|
```
|
|
579
601
|
|
|
602
|
+
**Why workerFactory?**
|
|
603
|
+
|
|
604
|
+
- Functions cannot be serialized via `postMessage` (causes `DataCloneError`)
|
|
605
|
+
- `registerProvider` in main thread doesn't affect Worker (separate registries)
|
|
606
|
+
- Custom worker file bundles your provider code into the Worker context
|
|
607
|
+
- Full control over parser logic, strategy implementation, and storage
|
|
608
|
+
|
|
580
609
|
|
|
581
610
|
### Custom Auth Methods (Advanced)
|
|
582
611
|
|