@atproto/lex 0.0.9 → 0.0.10

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +144 -1
  3. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atproto/lex
2
2
 
3
+ ## 0.0.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe), [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe), [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe), [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe), [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe), [`d78484f`](https://github.com/bluesky-social/atproto/commit/d78484f94d8ba1352ec66030115000d515c9dafe)]:
8
+ - @atproto/lex-data@0.0.7
9
+ - @atproto/lex-schema@0.0.8
10
+ - @atproto/lex-builder@0.0.10
11
+ - @atproto/lex-client@0.0.8
12
+ - @atproto/lex-installer@0.0.10
13
+ - @atproto/lex-json@0.0.7
14
+
3
15
  ## 0.0.9
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -458,6 +458,149 @@ const client = new Client(session)
458
458
 
459
459
  For detailed OAuth setup, see the [@atproto/oauth-client](../../../oauth/oauth-client) documentation.
460
460
 
461
+ #### Authenticated Client with Password
462
+
463
+ For simpler use cases (CLI tools, scripts, server-to-server), you can use password-based authentication with `@atproto/lex-password-session`:
464
+
465
+ ```bash
466
+ npm install @atproto/lex-password-session
467
+ ```
468
+
469
+ ```typescript
470
+ import { Client } from '@atproto/lex'
471
+ import { PasswordSession } from '@atproto/lex-password-session'
472
+ import * as app from './lexicons/app.js'
473
+
474
+ // Create a session with app password credentials
475
+ const session = await PasswordSession.create({
476
+ service: 'https://bsky.social',
477
+ identifier: 'alice.bsky.social', // handle or email
478
+ password: 'xxxx-xxxx-xxxx-xxxx', // App password (not your main password)
479
+
480
+ // Called when session is created or refreshed - persist the session data
481
+ onUpdated: (data) => {
482
+ saveToStorage(data) // Your persistence logic
483
+ },
484
+
485
+ // Called when session becomes invalid - clean up stored data
486
+ onDeleted: (data) => {
487
+ removeFromStorage(data.did)
488
+ },
489
+ })
490
+
491
+ // Use the session with a Client
492
+ const client = new Client(session)
493
+
494
+ const profile = await client.call(app.bsky.actor.getProfile, {
495
+ actor: 'atproto.com',
496
+ })
497
+ ```
498
+
499
+ **Resuming a Session**
500
+
501
+ Resume a previously persisted session. The `resume()` method validates the session by refreshing it:
502
+
503
+ ```typescript
504
+ const savedData = loadFromStorage() // Your retrieval logic
505
+
506
+ // Resume validates the session by refreshing it
507
+ // Throws if the session is definitively invalid
508
+ const session = await PasswordSession.resume(savedData, {
509
+ onUpdated: (data) => saveToStorage(data),
510
+ onDeleted: (data) => removeFromStorage(data.did),
511
+ })
512
+
513
+ const client = new Client(session)
514
+
515
+ // Access session properties
516
+ console.log(session.did) // User's DID
517
+ console.log(session.handle) // User's handle
518
+ console.log(session.destroyed) // false (session is active)
519
+ ```
520
+
521
+ **Logging Out**
522
+
523
+ ```typescript
524
+ await session.logout()
525
+ ```
526
+
527
+ **Deleting a Session Without Resuming**
528
+
529
+ Delete a stored session without needing to resume it first:
530
+
531
+ ```typescript
532
+ const savedData = loadFromStorage()
533
+
534
+ // Delete the session directly - throws on transient errors (network, server down)
535
+ await PasswordSession.delete(savedData)
536
+ ```
537
+
538
+ **Error Handling Hooks**
539
+
540
+ Handle transient errors (network issues, server unavailability) separately from permanent failures:
541
+
542
+ ```typescript
543
+ const session = await PasswordSession.create({
544
+ service: 'https://bsky.social',
545
+ identifier: 'alice.bsky.social',
546
+ password: 'xxxx-xxxx-xxxx-xxxx',
547
+
548
+ onUpdated: (data) => saveToStorage(data),
549
+ onDeleted: (data) => removeFromStorage(data.did),
550
+
551
+ // Called when refresh fails due to transient errors (network, server down)
552
+ // The session may still be valid - don't delete stored credentials
553
+ onUpdateFailure: (data, error) => {
554
+ console.warn('Session refresh failed, will retry:', error.message)
555
+ },
556
+
557
+ // Called when logout fails due to transient errors
558
+ // Consider retrying later to avoid orphaned sessions
559
+ onDeleteFailure: (data, error) => {
560
+ console.error('Logout failed, session may still be active:', error.message)
561
+ scheduleRetry(data) // Your retry logic
562
+ },
563
+ })
564
+ ```
565
+
566
+ **Handling Two-Factor Authentication (2FA)**
567
+
568
+ > [!CAUTION]
569
+ >
570
+ > Two-factor authentication only applies when using **main account credentials**, which is **strongly discouraged**. Password authentication should be used with [app passwords](https://bsky.app/settings/app-passwords) only because they are designed for programmatic access (bots, scripts, CLI tools). For user-facing applications, use OAuth via [@atproto/oauth-client](../../../oauth/oauth-client) which provides better security and user control.
571
+
572
+ ```typescript
573
+ import {
574
+ PasswordSession,
575
+ LexAuthFactorError,
576
+ } from '@atproto/lex-password-session'
577
+
578
+ async function loginWithMainCredentials(
579
+ identifier: string,
580
+ password: string,
581
+ authFactorToken?: string,
582
+ ): Promise<PasswordSession> {
583
+ try {
584
+ return await PasswordSession.create({
585
+ service: 'https://bsky.social',
586
+ identifier,
587
+ password,
588
+ authFactorToken,
589
+
590
+ onUpdated: (data) => saveToStorage(data),
591
+ onDeleted: (data) => removeFromStorage(data.did),
592
+ })
593
+ } catch (err) {
594
+ if (err instanceof LexAuthFactorError && !authFactorToken) {
595
+ // 2FA required
596
+ const token = await promptUserFor2FACode(err.message)
597
+ return loginWithMainCredentials(identifier, password, token)
598
+ }
599
+ throw err
600
+ }
601
+ }
602
+ ```
603
+
461
604
  #### Creating a Client from Another Client
462
605
 
463
606
  You can create a new `Client` instance from an existing client. The new client will share the same underlying configuration (authentication, headers, labelers, service proxy), with the ability to override specific settings.
@@ -893,7 +1036,7 @@ Various utilities for working with CIDs, string lengths, language tags, and low-
893
1036
  import {
894
1037
  // CID utilities
895
1038
  parseCid, // Parse CID string (throws on invalid)
896
- asCid, // Coerce to Cid or null
1039
+ ifCid, // Coerce to Cid or null
897
1040
  isCid, // Type guard for Cid values
898
1041
 
899
1042
  // Blob references
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "license": "MIT",
5
5
  "description": "Lexicon tooling for AT",
6
6
  "keywords": [
@@ -36,12 +36,12 @@
36
36
  "dependencies": {
37
37
  "tslib": "^2.8.1",
38
38
  "yargs": "^17.0.0",
39
- "@atproto/lex-builder": "0.0.9",
40
- "@atproto/lex-client": "0.0.7",
41
- "@atproto/lex-data": "0.0.6",
42
- "@atproto/lex-json": "0.0.6",
43
- "@atproto/lex-installer": "0.0.9",
44
- "@atproto/lex-schema": "0.0.7"
39
+ "@atproto/lex-builder": "0.0.10",
40
+ "@atproto/lex-client": "0.0.8",
41
+ "@atproto/lex-data": "0.0.7",
42
+ "@atproto/lex-json": "0.0.7",
43
+ "@atproto/lex-installer": "0.0.10",
44
+ "@atproto/lex-schema": "0.0.8"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/yargs": "^17.0.33",