@atproto/lex 0.0.8 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
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
+
15
+ ## 0.0.9
16
+
17
+ ### Patch Changes
18
+
19
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add an `indexFile` option that allows generating an "index.ts" file that re-exports every tld namespaces.
20
+
21
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Export everything from `@atproto/lex-data` and `@atproto/lex-json`
22
+
23
+ - Updated dependencies [[`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98), [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98)]:
24
+ - @atproto/lex-builder@0.0.9
25
+ - @atproto/lex-client@0.0.7
26
+ - @atproto/lex-data@0.0.6
27
+ - @atproto/lex-schema@0.0.7
28
+ - @atproto/lex-installer@0.0.9
29
+ - @atproto/lex-json@0.0.6
30
+
3
31
  ## 0.0.8
4
32
 
5
33
  ### Patch Changes
package/README.md CHANGED
@@ -53,7 +53,12 @@ app.bsky.actor.profile.$validate({
53
53
  - [TypeScript Schemas](#typescript-schemas)
54
54
  - [Generated Schema Structure](#generated-schema-structure)
55
55
  - [Type definitions](#type-definitions)
56
+ - [Building data](#building-data)
56
57
  - [Validation Helpers](#validation-helpers)
58
+ - [Data Model](#data-model)
59
+ - [Types](#types)
60
+ - [JSON Encoding](#json-encoding)
61
+ - [DAG-CBOR Encoding](#dag-cbor-encoding)
57
62
  - [Client API](#client-api)
58
63
  - [Creating a Client](#creating-a-client)
59
64
  - [Core Methods](#core-methods)
@@ -61,6 +66,8 @@ app.bsky.actor.profile.$validate({
61
66
  - [Authentication Methods](#authentication-methods)
62
67
  - [Labeler Configuration](#labeler-configuration)
63
68
  - [Low-Level XRPC](#low-level-xrpc)
69
+ - [Blob references](#blob-references)
70
+ - [Utilities](#utilities)
64
71
  - [Advanced Usage](#advanced-usage)
65
72
  - [Workflow Integration](#workflow-integration)
66
73
  - [Tree-Shaking](#tree-shaking)
@@ -89,7 +96,7 @@ This creates:
89
96
 
90
97
  > [!NOTE]
91
98
  >
92
- > The `lex` command might conflict with other binaries intalled on your system.
99
+ > The `lex` command might conflict with other binaries installed on your system.
93
100
  > If that happens, you can also run the CLI using `ts-lex`, `pnpm exec lex` or
94
101
  > `npx @atproto/lex`.
95
102
 
@@ -193,6 +200,7 @@ Options:
193
200
  - `--allowLegacyBlobs` - Allow generating schemas that accept legacy blob references (disabled by default; enable this if you encounter issues while processing records created a long time ago)
194
201
  - `--importExt <ext>` - File extension to use for import statements in generated files (default: `.js`). Use `--importExt ""` to generate extension-less imports
195
202
  - `--fileExt <ext>` - File extension to use for generated files (default: `.ts`)
203
+ - `--indexFile` - Generate an "index" file that re-exports all root-level namespaces (disabled by default)
196
204
 
197
205
  ### Generated Schema Structure
198
206
 
@@ -209,15 +217,25 @@ You can extract TypeScript types from the generated schemas for use in you appli
209
217
  ```typescript
210
218
  import * as app from './lexicons/app.js'
211
219
 
212
- // Extract the type for a post record
213
- type Post = app.bsky.feed.post.Main
220
+ function renderPost(p: app.bsky.feed.post.Main) {
221
+ console.log(p.$type) // 'app.bsky.feed.post'
222
+ console.log(p.text)
223
+ }
224
+ ```
214
225
 
215
- // Use the extracted types
216
- const post: Post = {
217
- $type: 'app.bsky.feed.post',
218
- text: 'Hello, AT Protocol!',
226
+ ### Building data
227
+
228
+ It is recommended to use the generated builders to create data that conforms to the schema. This ensures that all required fields are present.
229
+
230
+ ```typescript
231
+ import * as app from './lexicons/app.js'
232
+
233
+ // variable type will be inferred as "app.bsky.feed.post.Main"
234
+ const post = app.bsky.feed.post.$build({
235
+ // No need to specify $type when using $build
236
+ text: 'Hello, world!',
219
237
  createdAt: new Date().toISOString(),
220
- }
238
+ })
221
239
  ```
222
240
 
223
241
  ### Validation Helpers
@@ -284,6 +302,10 @@ try {
284
302
  }
285
303
  ```
286
304
 
305
+ > [!NOTE]
306
+ >
307
+ > The `$parse` method will apply defaults defined in the schema for optional fields, as well as data coercion (e.g., CID strings to Cid types). This means that the returned value might be different from the input data if defaults were applied. Disable this behavior by passing `{ allowTransform: false }` as the second argument to `$parse()`.
308
+
287
309
  #### `$validate(data)` - Get Validation Result
288
310
 
289
311
  Returns a detailed validation result object without throwing:
@@ -304,14 +326,18 @@ if (result.success) {
304
326
  }
305
327
  ```
306
328
 
329
+ > [!NOTE]
330
+ >
331
+ > Like `$parse`, the `$validate` method will apply defaults and coercion. Disable this behavior by passing `{ allowTransform: false }` as the second argument to `$validate()`.
332
+
307
333
  #### `$build(data)` - Build with Defaults
308
334
 
309
- Creates a valid object by applying defaults for optional fields:
335
+ Builds data without needing to specify the `$type` property, and properly types the result:
310
336
 
311
337
  ```typescript
312
338
  import * as app from './lexicons/app.js'
313
339
 
314
- // Build a like record with defaults (and without needing to specify $type)
340
+ // The type of the "like" variable will be "app.bsky.feed.like.Main"
315
341
  const like = app.bsky.feed.like.$build({
316
342
  subject: {
317
343
  uri: 'at://did:plc:abc/app.bsky.feed.post/123',
@@ -323,7 +349,7 @@ const like = app.bsky.feed.like.$build({
323
349
 
324
350
  #### `$isTypeOf(data)` - Type Discriminator
325
351
 
326
- Discriminates (already validated) data by `$type`, without re-validating. This is especially useful when working with union types:
352
+ Discriminates (pre-validated) data based on its `$type` property, without re-validating. This is especially useful when working with union types:
327
353
 
328
354
  ```typescript
329
355
  import { l } from '@atproto/lex'
@@ -340,6 +366,66 @@ if (app.bsky.feed.post.$isTypeOf(data)) {
340
366
  }
341
367
  ```
342
368
 
369
+ ## Data Model
370
+
371
+ The AT Protocol uses a [data model](https://atproto.com/specs/data-model) that extends JSON with two additional types: **CIDs** (content-addressed links) and **bytes**. This data is encoded as JSON for XRPC (HTTP API) or as [DAG-CBOR](https://ipld.io/docs/codecs/known/dag-cbor/) for storage and authentication (see [`@atproto/lex-cbor`](../lex-cbor)).
372
+
373
+ ### Types
374
+
375
+ ```typescript
376
+ import type {
377
+ LexValue,
378
+ LexMap,
379
+ LexScalar,
380
+ TypedLexMap,
381
+ Cid,
382
+ } from '@atproto/lex'
383
+ import { isLexValue, isLexMap, isTypedLexMap, isCid } from '@atproto/lex'
384
+
385
+ // LexScalar: number | string | boolean | null | Cid | Uint8Array
386
+ // LexValue: LexScalar | LexValue[] | { [key: string]?: LexValue }
387
+ // LexMap: { [key: string]?: LexValue }
388
+ // TypedLexMap: LexMap & { $type: string }
389
+ // Cid: Content Identifier (link by hash)
390
+
391
+ if (isTypedLexMap(data)) {
392
+ console.log(data.$type) // some string
393
+ }
394
+ ```
395
+
396
+ ### JSON Encoding
397
+
398
+ In JSON, CIDs are represented as `{"$link": "bafyrei..."}` and bytes as `{"$bytes": "base64..."}`:
399
+
400
+ ```typescript
401
+ import { lexParse, lexStringify, jsonToLex, lexToJson } from '@atproto/lex'
402
+
403
+ // Parse JSON string → data model (decodes $link and $bytes)
404
+ const data = lexParse('{"ref": {"$link": "bafyrei..."}}')
405
+
406
+ // Data model → JSON string (encodes CIDs and bytes)
407
+ const json = lexStringify({ ref: someCid, data: someBytes })
408
+
409
+ // Convert between parsed JSON objects and data model values
410
+ const lex = jsonToLex(jsonObject)
411
+ const obj = lexToJson(lexValue)
412
+ ```
413
+
414
+ ### DAG-CBOR Encoding
415
+
416
+ Use `@atproto/lex-cbor` to encode/decode the data model to/from DAG-CBOR format for storage and authentication:
417
+
418
+ ```typescript
419
+ import { encode, decode } from '@atproto/lex-cbor'
420
+ import type { LexValue } from '@atproto/lex'
421
+
422
+ // Encode data model to DAG-CBOR bytes
423
+ const cborBytes = encode(someLexValue)
424
+
425
+ // Decode DAG-CBOR bytes to data model
426
+ const lexValue: LexValue = decode(cborBytes)
427
+ ```
428
+
343
429
  ## Client API
344
430
 
345
431
  ### Creating a Client
@@ -372,6 +458,149 @@ const client = new Client(session)
372
458
 
373
459
  For detailed OAuth setup, see the [@atproto/oauth-client](../../../oauth/oauth-client) documentation.
374
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
+
375
604
  #### Creating a Client from Another Client
376
605
 
377
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.
@@ -767,6 +996,77 @@ console.log(response.headers)
767
996
  console.log(response.body)
768
997
  ```
769
998
 
999
+ ## Blob references
1000
+
1001
+ In AT Protocol, binary data (blobs) are referenced using `BlobRef`, which include metadata like MIME type and size. These references are what allow PDSs to determine which binary data ("files") is referenced by records.
1002
+
1003
+ ```typescript
1004
+ import { BlobRef, isBlobRef } from '@atproto/lex'
1005
+
1006
+ const blobRef: BlobRef = {
1007
+ $type: 'blob',
1008
+ ref: parseCid('bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku'),
1009
+ mimeType: 'image/png',
1010
+ size: 12345,
1011
+ }
1012
+
1013
+ if (isBlobRef(blobRef)) {
1014
+ console.log('Valid BlobRef:', blobRef.mimeType, blobRef.size)
1015
+ }
1016
+ ```
1017
+
1018
+ > [!NOTE]
1019
+ >
1020
+ > Historically, references to blobs were represented as simple objects with the following structure:
1021
+ >
1022
+ > ```typescript
1023
+ > type LegacyBlobRef = {
1024
+ > ref: string
1025
+ > mimeType: string
1026
+ > }
1027
+ > ```
1028
+ >
1029
+ > These should no longer be used for new records, but existing records using this format might still be encountered. To handle legacy blob references when validating data, enable the `--allowLegacyBlobs` flag when generating TypeScript schemas with `lex build`. You can use `isLegacyBlobRef()` from `@atproto/lex` to discriminate legacy blob references.
1030
+
1031
+ ## Utilities
1032
+
1033
+ Various utilities for working with CIDs, string lengths, language tags, and low-level JSON encoding are available:
1034
+
1035
+ ```typescript
1036
+ import {
1037
+ // CID utilities
1038
+ parseCid, // Parse CID string (throws on invalid)
1039
+ ifCid, // Coerce to Cid or null
1040
+ isCid, // Type guard for Cid values
1041
+
1042
+ // Blob references
1043
+ BlobRef, // { $type: 'blob', ref: Cid, mimeType: string, size: number }
1044
+ isBlobRef, // Type guard for BlobRef objects
1045
+
1046
+ // Equality
1047
+ lexEquals, // Deep equality (handles CIDs and bytes)
1048
+
1049
+ // String length for Lexicon validation
1050
+ graphemeLen, // Count user-perceived characters
1051
+ utf8Len, // Count UTF-8 bytes
1052
+
1053
+ // Language tag validation (BCP-47)
1054
+ isLanguageString, // Validate language tags (e.g., 'en', 'pt-BR')
1055
+
1056
+ // Low-level JSON encoding helpers
1057
+ parseLexLink, // { $link: string } → Cid
1058
+ encodeLexLink, // Cid → { $link: string }
1059
+ parseLexBytes, // { $bytes: string } → Uint8Array
1060
+ encodeLexBytes, // Uint8Array → { $bytes: string }
1061
+ } from '@atproto/lex'
1062
+
1063
+ // Examples
1064
+ const cid = parseCid('bafyreiabc...')
1065
+ graphemeLen('👨‍👩‍👧‍👦') // 1
1066
+ utf8Len('👨‍👩‍👧‍👦') // 25
1067
+ isLanguageString('en-US') // true
1068
+ ```
1069
+
770
1070
  ## Advanced Usage
771
1071
 
772
1072
  ### Workflow Integration
package/bin/lex CHANGED
@@ -94,6 +94,12 @@ yargs(hideBin(process.argv))
94
94
  describe:
95
95
  'file extension to use for generated files (e.g. ".ts", ".mts", ".cts")',
96
96
  },
97
+ indexFile: {
98
+ type: 'boolean',
99
+ default: false,
100
+ describe:
101
+ 'generate an "index.<fileExt>" file that exports all root-level namespaces',
102
+ },
97
103
  ignoreInvalidLexicons: {
98
104
  type: 'boolean',
99
105
  default: false,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from '@atproto/lex-data';
2
+ export * from '@atproto/lex-json';
1
3
  export * from '@atproto/lex-schema';
2
4
  export * from '@atproto/lex-client';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("@atproto/lex-data"), exports);
5
+ tslib_1.__exportStar(require("@atproto/lex-json"), exports);
4
6
  tslib_1.__exportStar(require("@atproto/lex-schema"), exports);
5
7
  tslib_1.__exportStar(require("@atproto/lex-client"), exports);
6
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,8DAAmC;AACnC,8DAAmC","sourcesContent":["export * from '@atproto/lex-schema'\nexport * from '@atproto/lex-client'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4DAAiC;AACjC,4DAAiC;AACjC,8DAAmC;AACnC,8DAAmC","sourcesContent":["export * from '@atproto/lex-data'\nexport * from '@atproto/lex-json'\nexport * from '@atproto/lex-schema'\nexport * from '@atproto/lex-client'\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex",
3
- "version": "0.0.8",
3
+ "version": "0.0.10",
4
4
  "license": "MIT",
5
5
  "description": "Lexicon tooling for AT",
6
6
  "keywords": [
@@ -36,10 +36,12 @@
36
36
  "dependencies": {
37
37
  "tslib": "^2.8.1",
38
38
  "yargs": "^17.0.0",
39
- "@atproto/lex-builder": "0.0.8",
40
- "@atproto/lex-client": "0.0.6",
41
- "@atproto/lex-installer": "0.0.8",
42
- "@atproto/lex-schema": "0.0.6"
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"
43
45
  },
44
46
  "devDependencies": {
45
47
  "@types/yargs": "^17.0.33",