@atcute/lex-cli 2.4.0 → 2.5.0

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 (57) hide show
  1. package/README.md +40 -8
  2. package/dist/cli.js +10 -168
  3. package/dist/cli.js.map +1 -1
  4. package/dist/codegen.d.ts.map +1 -1
  5. package/dist/codegen.js +76 -78
  6. package/dist/codegen.js.map +1 -1
  7. package/dist/commands/export.d.ts +13 -0
  8. package/dist/commands/export.d.ts.map +1 -0
  9. package/dist/commands/export.js +76 -0
  10. package/dist/commands/export.js.map +1 -0
  11. package/dist/commands/generate.d.ts +13 -0
  12. package/dist/commands/generate.d.ts.map +1 -0
  13. package/dist/commands/generate.js +136 -0
  14. package/dist/commands/generate.js.map +1 -0
  15. package/dist/commands/pull.d.ts +13 -0
  16. package/dist/commands/pull.d.ts.map +1 -0
  17. package/dist/{pull.js → commands/pull.js} +35 -81
  18. package/dist/commands/pull.js.map +1 -0
  19. package/dist/config.d.ts +68 -6
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +54 -3
  22. package/dist/config.js.map +1 -1
  23. package/dist/lexicon-loader.d.ts +17 -0
  24. package/dist/lexicon-loader.d.ts.map +1 -0
  25. package/dist/lexicon-loader.js +167 -0
  26. package/dist/lexicon-loader.js.map +1 -0
  27. package/dist/pull-sources/atproto.d.ts +9 -0
  28. package/dist/pull-sources/atproto.d.ts.map +1 -0
  29. package/dist/pull-sources/atproto.js +192 -0
  30. package/dist/pull-sources/atproto.js.map +1 -0
  31. package/dist/pull-sources/git.d.ts +11 -0
  32. package/dist/pull-sources/git.d.ts.map +1 -0
  33. package/dist/pull-sources/git.js +80 -0
  34. package/dist/pull-sources/git.js.map +1 -0
  35. package/dist/pull-sources/types.d.ts +16 -0
  36. package/dist/pull-sources/types.d.ts.map +1 -0
  37. package/dist/pull-sources/types.js +2 -0
  38. package/dist/pull-sources/types.js.map +1 -0
  39. package/dist/shared-options.d.ts +6 -0
  40. package/dist/shared-options.d.ts.map +1 -0
  41. package/dist/shared-options.js +11 -0
  42. package/dist/shared-options.js.map +1 -0
  43. package/package.json +10 -7
  44. package/src/cli.ts +9 -210
  45. package/src/codegen.ts +90 -88
  46. package/src/commands/export.ts +106 -0
  47. package/src/commands/generate.ts +170 -0
  48. package/src/{pull.ts → commands/pull.ts} +49 -116
  49. package/src/config.ts +67 -4
  50. package/src/lexicon-loader.ts +199 -0
  51. package/src/pull-sources/atproto.ts +243 -0
  52. package/src/pull-sources/git.ts +103 -0
  53. package/src/pull-sources/types.ts +18 -0
  54. package/src/shared-options.ts +13 -0
  55. package/dist/pull.d.ts +0 -7
  56. package/dist/pull.d.ts.map +0 -1
  57. package/dist/pull.js.map +0 -1
@@ -0,0 +1,243 @@
1
+ import { getPdsEndpoint, isAtprotoDid } from '@atcute/identity';
2
+ import type { DidDocumentResolver } from '@atcute/identity-resolver';
3
+ import {
4
+ CompositeDidDocumentResolver,
5
+ CompositeHandleResolver,
6
+ DohJsonHandleResolver,
7
+ PlcDidDocumentResolver,
8
+ WebDidDocumentResolver,
9
+ WellKnownHandleResolver,
10
+ } from '@atcute/identity-resolver';
11
+ import { refineLexiconDoc, type LexiconDoc } from '@atcute/lexicon-doc';
12
+ import { DohJsonLexiconAuthorityResolver, LexiconSchemaResolver } from '@atcute/lexicon-resolver';
13
+ import {
14
+ isHandle,
15
+ isNsid,
16
+ parseCanonicalResourceUri,
17
+ type AtprotoDid,
18
+ type Nsid,
19
+ } from '@atcute/lexicons/syntax';
20
+ import pc from 'picocolors';
21
+
22
+ import type { AtprotoSourceConfig } from '../config.js';
23
+ import type { PullResult, SourceLocation } from './types.js';
24
+
25
+ /**
26
+ * discovers all published lexicons for an authority by listing records in the
27
+ * com.atproto.lexicon.schema collection
28
+ * @param authority the authority DID
29
+ * @param didResolver DID document resolver
30
+ * @returns array of NSID strings
31
+ */
32
+ const discoverLexiconsForAuthority = async (
33
+ authority: AtprotoDid,
34
+ didResolver: DidDocumentResolver,
35
+ ): Promise<Nsid[]> => {
36
+ // resolve DID to get PDS endpoint
37
+ const didDocument = await didResolver.resolve(authority);
38
+ const pdsEndpoint = getPdsEndpoint(didDocument);
39
+
40
+ if (!pdsEndpoint) {
41
+ throw new Error(`no pds service in did document; did=${authority}`);
42
+ }
43
+
44
+ // call com.atproto.repo.listRecords to get all lexicon schema records
45
+ const nsids: Nsid[] = [];
46
+ let cursor: string | undefined;
47
+
48
+ do {
49
+ const url = new URL('/xrpc/com.atproto.repo.listRecords', pdsEndpoint);
50
+ url.searchParams.set('repo', authority);
51
+ url.searchParams.set('collection', 'com.atproto.lexicon.schema');
52
+ url.searchParams.set('limit', '100');
53
+ if (cursor) {
54
+ url.searchParams.set('cursor', cursor);
55
+ }
56
+
57
+ const response = await fetch(url, {
58
+ headers: { accept: 'application/json' },
59
+ });
60
+
61
+ if (!response.ok) {
62
+ throw new Error(`http ${response.status} when listing records`);
63
+ }
64
+
65
+ const data = (await response.json()) as {
66
+ records: Array<{ uri: string; value: unknown }>;
67
+ cursor?: string;
68
+ };
69
+
70
+ // extract NSIDs from record keys (the rkey in at://did/collection/rkey)
71
+ for (const record of data.records) {
72
+ const r = parseCanonicalResourceUri(record.uri);
73
+ if (!r.ok) {
74
+ continue;
75
+ }
76
+
77
+ const nsid = r.value.rkey;
78
+ if (!isNsid(nsid)) {
79
+ continue;
80
+ }
81
+
82
+ nsids.push(nsid);
83
+ }
84
+
85
+ cursor = data.cursor;
86
+ } while (cursor);
87
+
88
+ return nsids;
89
+ };
90
+
91
+ /**
92
+ * pulls lexicon documents from AT Protocol network resolution
93
+ * @param source atproto source configuration
94
+ * @returns pulled lexicons and ISO timestamp
95
+ */
96
+ export const pullAtprotoSource = async (source: AtprotoSourceConfig): Promise<PullResult> => {
97
+ // create resolver instances (reusable across NSIDs)
98
+ const authorityResolver = new DohJsonLexiconAuthorityResolver({
99
+ dohUrl: 'https://cloudflare-dns.com/dns-query',
100
+ });
101
+
102
+ const didResolver = new CompositeDidDocumentResolver({
103
+ methods: {
104
+ plc: new PlcDidDocumentResolver(),
105
+ web: new WebDidDocumentResolver(),
106
+ },
107
+ });
108
+
109
+ const schemaResolver = new LexiconSchemaResolver({
110
+ didDocumentResolver: didResolver,
111
+ });
112
+
113
+ const handleResolver = new CompositeHandleResolver({
114
+ strategy: 'race',
115
+ methods: {
116
+ http: new WellKnownHandleResolver(),
117
+ dns: new DohJsonHandleResolver({
118
+ dohUrl: 'https://cloudflare-dns.com/dns-query',
119
+ }),
120
+ },
121
+ });
122
+
123
+ const pulled = new Map<string, { nsid: string; doc: LexiconDoc; location: SourceLocation }>();
124
+ const errors: Array<{ nsid: string; error: Error }> = [];
125
+
126
+ let nsids: Nsid[];
127
+ let authorityDid: AtprotoDid | null = null;
128
+ let sourceDesc: string;
129
+ let sourceName: string | null = null;
130
+
131
+ if (source.mode === 'nsids') {
132
+ nsids = source.nsids;
133
+ sourceDesc = `atproto (${nsids.length} nsids)`;
134
+ } else {
135
+ // mode 2: authority-based
136
+ // step 2a: resolve authority (handle -> DID if needed)
137
+ let resolvedDid: AtprotoDid;
138
+ const handle = isHandle(source.authority) ? source.authority : null;
139
+
140
+ try {
141
+ if (isAtprotoDid(source.authority)) {
142
+ resolvedDid = source.authority;
143
+ } else if (handle) {
144
+ resolvedDid = await handleResolver.resolve(handle);
145
+ } else {
146
+ console.error(pc.bold(pc.red(`invalid authority: ${source.authority}`)));
147
+ console.error(`must be a valid DID or handle`);
148
+ process.exit(1);
149
+ }
150
+
151
+ authorityDid = resolvedDid;
152
+ sourceDesc = `atproto (authority: ${authorityDid})`;
153
+ sourceName = handle ?? authorityDid;
154
+ } catch (err) {
155
+ console.error(pc.bold(pc.red(`failed to resolve authority: ${source.authority}`)));
156
+ console.error(err);
157
+ process.exit(1);
158
+ }
159
+
160
+ // step 2b: discover all lexicons for this authority
161
+ try {
162
+ nsids = await discoverLexiconsForAuthority(authorityDid, didResolver);
163
+ } catch (err) {
164
+ console.error(pc.bold(pc.red(`failed to discover lexicons for ${sourceName}`)));
165
+ console.error(err);
166
+ process.exit(1);
167
+ }
168
+
169
+ // step 2c: filter by pattern if specified
170
+ if (source.pattern) {
171
+ nsids = nsids.filter((nsid) => {
172
+ return source.pattern!.some((pattern) => {
173
+ if (pattern.endsWith('.*')) {
174
+ const prefix = pattern.slice(0, -2);
175
+ return nsid === prefix || nsid.startsWith(prefix + '.');
176
+ }
177
+ return nsid === pattern;
178
+ });
179
+ });
180
+ }
181
+
182
+ if (nsids.length === 0) {
183
+ console.warn(pc.yellow(`warning: no lexicons found for ${sourceName}`));
184
+ }
185
+ }
186
+
187
+ // fetch each NSID
188
+ let fetchedCount = 0;
189
+ for (const nsid of nsids) {
190
+ try {
191
+ // step 1: resolve authority from NSID (DNS)
192
+ const resolvedAuthority = await authorityResolver.resolve(nsid as Nsid);
193
+
194
+ // step 2: cross-verify authority if in authority-based mode
195
+ if (authorityDid && resolvedAuthority !== authorityDid) {
196
+ throw new Error(
197
+ `authority mismatch: NSID ${nsid} claims authority ${resolvedAuthority} but expected ${authorityDid}`,
198
+ );
199
+ }
200
+
201
+ // step 3: fetch schema from authority's PDS
202
+ const resolved = await schemaResolver.resolve(resolvedAuthority, nsid as Nsid);
203
+
204
+ // step 4: lint the lexicon document
205
+ const issues = refineLexiconDoc(resolved.schema, true);
206
+ if (issues.length > 0) {
207
+ const messages = issues.map((i) => ` ${i.path}: ${i.message}`).join('\n');
208
+ throw new Error(`lint validation failed:\n${messages}`);
209
+ }
210
+
211
+ // create in-memory location (no file on disk yet)
212
+ const location: SourceLocation = {
213
+ absolutePath: `<atproto:${nsid}>`,
214
+ relativePath: `${nsid}.json`,
215
+ sourceDescription: sourceDesc,
216
+ };
217
+
218
+ pulled.set(nsid, {
219
+ nsid,
220
+ doc: resolved.schema,
221
+ location,
222
+ });
223
+ fetchedCount++;
224
+ console.log(`${pc.green('+')} ${nsid}`);
225
+ } catch (err) {
226
+ // best-effort: collect errors but continue
227
+ errors.push({ nsid, error: err as Error });
228
+ }
229
+ }
230
+
231
+ // report all errors at end
232
+ if (errors.length > 0) {
233
+ console.warn(pc.yellow(`\nwarning: failed to fetch ${errors.length} lexicon(s):`));
234
+ for (const { nsid, error } of errors) {
235
+ console.warn(` - ${nsid}: ${error.message}`);
236
+ }
237
+ }
238
+
239
+ const suffix = sourceName ? ` from ${pc.cyan(sourceName)}` : '';
240
+ console.log(`pulled ${pc.cyan(fetchedCount.toString())} lexicons${suffix}`);
241
+
242
+ return { pulled };
243
+ };
@@ -0,0 +1,103 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+
5
+ import type { LexiconDoc } from '@atcute/lexicon-doc';
6
+ import pc from 'picocolors';
7
+
8
+ import { runGit, GitError } from '../git.js';
9
+ import type { GitSourceConfig } from '../config.js';
10
+ import type { PullResult, PulledLexicon, SourceLocation } from './types.js';
11
+
12
+ /**
13
+ * pulls lexicon documents from a git repository source
14
+ * @param source git source configuration
15
+ * @param parseLexiconFile function to parse and validate lexicon files
16
+ * @returns pulled lexicons and commit hash
17
+ */
18
+ export const pullGitSource = async (
19
+ source: GitSourceConfig,
20
+ parseLexiconFile: (loc: SourceLocation) => Promise<LexiconDoc>,
21
+ ): Promise<PullResult> => {
22
+ const tempParent = await fs.mkdtemp(path.join(os.tmpdir(), 'lex-cli-pull-'));
23
+
24
+ const cloneDir = path.join(tempParent, 'repo');
25
+
26
+ try {
27
+ await runGit(
28
+ [
29
+ 'clone',
30
+ '--filter=blob:none',
31
+ '--depth',
32
+ '1',
33
+ '--sparse',
34
+ ...(source.ref ? ['--branch', source.ref, '--single-branch'] : []),
35
+ source.remote,
36
+ cloneDir,
37
+ ],
38
+ { timeoutMs: 60_000 },
39
+ );
40
+ } catch (err) {
41
+ if (err instanceof GitError) {
42
+ console.error(pc.bold(pc.red(`git clone failed for ${source.remote}:`)));
43
+ console.error(err.stderr || err.message);
44
+ process.exit(1);
45
+ }
46
+
47
+ throw err;
48
+ }
49
+
50
+ try {
51
+ await runGit(['-C', cloneDir, 'sparse-checkout', 'set', '--no-cone', ...source.pattern], {
52
+ timeoutMs: 30_000,
53
+ });
54
+ } catch (err) {
55
+ if (err instanceof GitError) {
56
+ console.error(pc.bold(pc.red(`git sparse-checkout failed for ${source.remote}:`)));
57
+ console.error(err.stderr || err.message);
58
+ process.exit(1);
59
+ }
60
+
61
+ throw err;
62
+ }
63
+
64
+ const pulled = new Map<string, PulledLexicon>();
65
+
66
+ for await (const filename of fs.glob(source.pattern, { cwd: cloneDir })) {
67
+ const absolute = path.join(cloneDir, filename);
68
+ const stat = await fs.stat(absolute);
69
+
70
+ if (!stat.isFile()) {
71
+ continue;
72
+ }
73
+
74
+ const location: SourceLocation = {
75
+ absolutePath: absolute,
76
+ relativePath: filename,
77
+ sourceDescription: source.remote,
78
+ };
79
+
80
+ const doc = await parseLexiconFile(location);
81
+
82
+ pulled.set(doc.id, { nsid: doc.id, doc, location });
83
+ }
84
+
85
+ // get the commit hash
86
+ let rev: string;
87
+ try {
88
+ const result = await runGit(['-C', cloneDir, 'rev-parse', 'HEAD'], { timeoutMs: 10_000 });
89
+ rev = result.stdout.trim();
90
+ } catch (err) {
91
+ if (err instanceof GitError) {
92
+ console.error(pc.bold(pc.red(`git rev-parse failed for ${source.remote}:`)));
93
+ console.error(err.stderr || err.message);
94
+ process.exit(1);
95
+ }
96
+
97
+ throw err;
98
+ }
99
+
100
+ await fs.rm(tempParent, { recursive: true, force: true });
101
+
102
+ return { pulled, rev };
103
+ };
@@ -0,0 +1,18 @@
1
+ import type { LexiconDoc } from '@atcute/lexicon-doc';
2
+
3
+ export interface SourceLocation {
4
+ absolutePath: string;
5
+ relativePath: string;
6
+ sourceDescription: string;
7
+ }
8
+
9
+ export interface PulledLexicon {
10
+ nsid: string;
11
+ doc: LexiconDoc;
12
+ location: SourceLocation;
13
+ }
14
+
15
+ export interface PullResult {
16
+ pulled: Map<string, PulledLexicon>;
17
+ rev?: string;
18
+ }
@@ -0,0 +1,13 @@
1
+ import { object } from '@optique/core/constructs';
2
+ import { message } from '@optique/core/message';
3
+ import { optional } from '@optique/core/modifiers';
4
+ import { option } from '@optique/core/primitives';
5
+ import { path as pathParser } from '@optique/run/valueparser';
6
+
7
+ export const sharedOptions = object(`Global options`, {
8
+ config: optional(
9
+ option('-c', '--config', pathParser({ metavar: 'CONFIG' }), {
10
+ description: message`path to the lexicon configuration file. defaults to searching for lex.config.js or lex.config.ts in the current directory.`,
11
+ }),
12
+ ),
13
+ });
package/dist/pull.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { NormalizedConfig } from './config.js';
2
- /**
3
- * pulls lexicon documents from configured sources and writes them to disk using nsid-based paths.
4
- * @param config normalized lex-cli configuration
5
- */
6
- export declare const runPull: (config: NormalizedConfig) => Promise<void>;
7
- //# sourceMappingURL=pull.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAA4B,MAAM,aAAa,CAAC;AAkP9E;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAU,QAAQ,gBAAgB,KAAG,OAAO,CAAC,IAAI,CA0CpE,CAAC"}
package/dist/pull.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}