@atcute/lex-cli 2.7.0 → 2.8.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/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +35 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/export.d.ts +2 -8
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +7 -14
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/generate.d.ts +2 -8
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +61 -39
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/pull.d.ts +2 -8
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +1 -12
- package/dist/commands/pull.js.map +1 -1
- package/dist/config.d.ts +30 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +56 -12
- package/dist/config.js.map +1 -1
- package/dist/pull-sources/git.d.ts.map +1 -1
- package/dist/pull-sources/git.js +61 -58
- package/dist/pull-sources/git.js.map +1 -1
- package/package.json +6 -6
- package/src/cli.ts +65 -7
- package/src/commands/export.ts +9 -24
- package/src/commands/generate.ts +72 -50
- package/src/commands/pull.ts +2 -22
- package/src/config.ts +77 -23
- package/src/pull-sources/git.ts +64 -63
- package/dist/shared-options.d.ts +0 -6
- package/dist/shared-options.d.ts.map +0 -1
- package/dist/shared-options.js +0 -11
- package/dist/shared-options.js.map +0 -1
- package/src/shared-options.ts +0 -13
package/src/commands/pull.ts
CHANGED
|
@@ -3,34 +3,14 @@ import * as path from 'node:path';
|
|
|
3
3
|
|
|
4
4
|
import { lexiconDoc, refineLexiconDoc, type LexiconDoc } from '@atcute/lexicon-doc';
|
|
5
5
|
|
|
6
|
-
import { merge, object } from '@optique/core/constructs';
|
|
7
|
-
import { message } from '@optique/core/message';
|
|
8
|
-
import { type InferValue } from '@optique/core/parser';
|
|
9
|
-
import { command, constant } from '@optique/core/primitives';
|
|
10
6
|
import pc from 'picocolors';
|
|
11
7
|
|
|
8
|
+
import type { PullCommand } from '../cli.ts';
|
|
12
9
|
import { loadConfig, type NormalizedConfig, type PullConfig, type SourceConfig } from '../config.ts';
|
|
13
10
|
import { createFormatter, type Formatter } from '../formatter.ts';
|
|
14
11
|
import { pullAtprotoSource } from '../pull-sources/atproto.ts';
|
|
15
12
|
import { pullGitSource } from '../pull-sources/git.ts';
|
|
16
13
|
import type { PullResult, PulledLexicon, SourceLocation } from '../pull-sources/types.ts';
|
|
17
|
-
import { sharedOptions } from '../shared-options.ts';
|
|
18
|
-
|
|
19
|
-
export const pullCommandSchema = command(
|
|
20
|
-
'pull',
|
|
21
|
-
merge(
|
|
22
|
-
object({
|
|
23
|
-
type: constant('pull'),
|
|
24
|
-
}),
|
|
25
|
-
sharedOptions,
|
|
26
|
-
),
|
|
27
|
-
{
|
|
28
|
-
brief: message`pull lexicon documents from configured sources`,
|
|
29
|
-
description: message`fetches lexicon documents from configured git repositories and writes them to the output directory.`,
|
|
30
|
-
},
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
export type PullCommand = InferValue<typeof pullCommandSchema>;
|
|
34
14
|
|
|
35
15
|
interface SourceRevision {
|
|
36
16
|
source: SourceConfig;
|
|
@@ -180,7 +160,7 @@ const writeSourceReadme = async (
|
|
|
180
160
|
* runs the pull command to fetch lexicon documents from configured sources
|
|
181
161
|
* @param args parsed command arguments
|
|
182
162
|
*/
|
|
183
|
-
export const
|
|
163
|
+
export const handler = async (args: PullCommand): Promise<void> => {
|
|
184
164
|
const config = await loadConfig(args.config);
|
|
185
165
|
const pullConfig = ensurePullConfig(config);
|
|
186
166
|
|
package/src/config.ts
CHANGED
|
@@ -79,15 +79,6 @@ const formatterConfigSchema = v.union(
|
|
|
79
79
|
}),
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
-
export type GitSourceConfig = v.Infer<typeof gitSourceConfigSchema>;
|
|
83
|
-
export type AtprotoNsidsSourceConfig = v.Infer<typeof atprotoNsidsSourceConfigSchema>;
|
|
84
|
-
export type AtprotoAuthoritySourceConfig = v.Infer<typeof atprotoAuthoritySourceConfigSchema>;
|
|
85
|
-
export type AtprotoSourceConfig = v.Infer<typeof atprotoSourceConfigSchema>;
|
|
86
|
-
export type SourceConfig = v.Infer<typeof sourceConfigSchema>;
|
|
87
|
-
export type PullConfig = v.Infer<typeof pullConfigSchema>;
|
|
88
|
-
export type ExportConfig = v.Infer<typeof exportConfigSchema>;
|
|
89
|
-
export type FormatterConfig = v.Infer<typeof formatterConfigSchema>;
|
|
90
|
-
|
|
91
82
|
const isValidLexiconPattern = (pattern: string): boolean => {
|
|
92
83
|
if (pattern.endsWith('.*')) {
|
|
93
84
|
return isNsid(`${pattern.slice(0, -2)}.x`);
|
|
@@ -127,32 +118,71 @@ const importMappingSchema: v.Type<ImportMapping> = v.object({
|
|
|
127
118
|
imports: mappingImports,
|
|
128
119
|
});
|
|
129
120
|
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
const modulesConfigSchema = v
|
|
122
|
+
.object({
|
|
123
|
+
importSuffix: v
|
|
124
|
+
.string()
|
|
125
|
+
.assert((value) => value.length > 0, `must not be empty`)
|
|
126
|
+
.optional(),
|
|
127
|
+
})
|
|
128
|
+
.partial();
|
|
129
|
+
|
|
130
|
+
const generateConfigSchema = v.object({
|
|
131
|
+
outdir: v
|
|
132
|
+
.string()
|
|
133
|
+
.assert((value) => value.length > 0, `must not be empty`)
|
|
134
|
+
.optional(),
|
|
132
135
|
files: v
|
|
133
136
|
.array(v.string().assert((value) => value.length > 0, `must not be empty`))
|
|
134
|
-
.assert((value) => value.length > 0, `must include at least one glob pattern`)
|
|
137
|
+
.assert((value) => value.length > 0, `must include at least one glob pattern`)
|
|
138
|
+
.optional(),
|
|
135
139
|
imports: v.array(v.string().assert((value) => value.length > 0, `must not be empty`)).optional(),
|
|
136
140
|
mappings: v.array(importMappingSchema).optional(),
|
|
137
|
-
modules:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
modules: modulesConfigSchema.optional(),
|
|
142
|
+
clean: v.boolean().optional(),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
export type GitSourceConfig = v.Infer<typeof gitSourceConfigSchema>;
|
|
146
|
+
export type AtprotoNsidsSourceConfig = v.Infer<typeof atprotoNsidsSourceConfigSchema>;
|
|
147
|
+
export type AtprotoAuthoritySourceConfig = v.Infer<typeof atprotoAuthoritySourceConfigSchema>;
|
|
148
|
+
export type AtprotoSourceConfig = v.Infer<typeof atprotoSourceConfigSchema>;
|
|
149
|
+
export type SourceConfig = v.Infer<typeof sourceConfigSchema>;
|
|
150
|
+
export type PullConfig = v.Infer<typeof pullConfigSchema>;
|
|
151
|
+
export type ExportConfig = v.Infer<typeof exportConfigSchema>;
|
|
152
|
+
export type FormatterConfig = v.Infer<typeof formatterConfigSchema>;
|
|
153
|
+
export type GenerateConfig = v.Infer<typeof generateConfigSchema>;
|
|
154
|
+
|
|
155
|
+
export const lexiconConfigSchema = v.object({
|
|
156
|
+
/** @deprecated moved to `generate.outdir` */
|
|
157
|
+
outdir: v
|
|
158
|
+
.string()
|
|
159
|
+
.assert((value) => value.length > 0, `must not be empty`)
|
|
160
|
+
.optional(),
|
|
161
|
+
/** @deprecated moved to `generate.files` */
|
|
162
|
+
files: v
|
|
163
|
+
.array(v.string().assert((value) => value.length > 0, `must not be empty`))
|
|
164
|
+
.assert((value) => value.length > 0, `must include at least one glob pattern`)
|
|
145
165
|
.optional(),
|
|
166
|
+
/** @deprecated moved to `generate.imports` */
|
|
167
|
+
imports: v.array(v.string().assert((value) => value.length > 0, `must not be empty`)).optional(),
|
|
168
|
+
/** @deprecated moved to `generate.mappings` */
|
|
169
|
+
mappings: v.array(importMappingSchema).optional(),
|
|
170
|
+
/** @deprecated moved to `generate.modules` */
|
|
171
|
+
modules: modulesConfigSchema.optional(),
|
|
146
172
|
formatter: formatterConfigSchema.optional((): FormatterConfig => ({ type: 'prettier' })),
|
|
173
|
+
generate: generateConfigSchema.optional(),
|
|
147
174
|
pull: pullConfigSchema.optional(),
|
|
148
175
|
export: exportConfigSchema.optional(),
|
|
149
176
|
});
|
|
150
177
|
|
|
151
178
|
export type LexiconConfig = v.Infer<typeof lexiconConfigSchema>;
|
|
152
179
|
|
|
153
|
-
export
|
|
180
|
+
export type NormalizedConfig = Omit<
|
|
181
|
+
LexiconConfig,
|
|
182
|
+
'outdir' | 'files' | 'imports' | 'mappings' | 'modules'
|
|
183
|
+
> & {
|
|
154
184
|
root: string;
|
|
155
|
-
}
|
|
185
|
+
};
|
|
156
186
|
|
|
157
187
|
export const loadConfig = async (configPath?: string): Promise<NormalizedConfig> => {
|
|
158
188
|
let configFilename: string | undefined;
|
|
@@ -207,5 +237,29 @@ export const loadConfig = async (configPath?: string): Promise<NormalizedConfig>
|
|
|
207
237
|
process.exit(1);
|
|
208
238
|
}
|
|
209
239
|
|
|
210
|
-
|
|
240
|
+
const { outdir, files, imports, mappings, modules, generate, ...rest } = configResult.value;
|
|
241
|
+
|
|
242
|
+
// back-compat: top-level generate options were moved into `generate.*`. merge the legacy
|
|
243
|
+
// top-level values into `generate`, with nested `generate.*` winning on conflicts. the result
|
|
244
|
+
// is only present if at least one generate-related option was provided anywhere.
|
|
245
|
+
const hasLegacyTopLevel =
|
|
246
|
+
outdir !== undefined ||
|
|
247
|
+
files !== undefined ||
|
|
248
|
+
imports !== undefined ||
|
|
249
|
+
mappings !== undefined ||
|
|
250
|
+
modules !== undefined;
|
|
251
|
+
|
|
252
|
+
let normalizedGenerate: GenerateConfig | undefined;
|
|
253
|
+
if (generate || hasLegacyTopLevel) {
|
|
254
|
+
normalizedGenerate = {
|
|
255
|
+
outdir: generate?.outdir ?? outdir,
|
|
256
|
+
files: generate?.files ?? files,
|
|
257
|
+
imports: generate?.imports ?? imports,
|
|
258
|
+
mappings: generate?.mappings ?? mappings,
|
|
259
|
+
modules: generate?.modules ?? modules,
|
|
260
|
+
clean: generate?.clean,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return { ...rest, generate: normalizedGenerate, root: configDirname };
|
|
211
265
|
};
|
package/src/pull-sources/git.ts
CHANGED
|
@@ -26,80 +26,81 @@ export const pullGitSource = async (
|
|
|
26
26
|
const cloneDir = path.join(tempParent, 'repo');
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
try {
|
|
30
|
+
await runGit(
|
|
31
|
+
[
|
|
32
|
+
'clone',
|
|
33
|
+
'--filter=blob:none',
|
|
34
|
+
'--depth',
|
|
35
|
+
'1',
|
|
36
|
+
'--sparse',
|
|
37
|
+
...(source.ref ? ['--branch', source.ref, '--single-branch'] : []),
|
|
38
|
+
source.remote,
|
|
39
|
+
cloneDir,
|
|
40
|
+
],
|
|
41
|
+
{ timeoutMs: 60_000 },
|
|
42
|
+
);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
if (err instanceof GitError) {
|
|
45
|
+
console.error(pc.bold(pc.red(`git clone failed for ${source.remote}:`)));
|
|
46
|
+
console.error(err.stderr || err.message);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
throw err;
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
try {
|
|
54
|
+
await runGit(['-C', cloneDir, 'sparse-checkout', 'set', '--no-cone', ...source.pattern], {
|
|
55
|
+
timeoutMs: 30_000,
|
|
56
|
+
});
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (err instanceof GitError) {
|
|
59
|
+
console.error(pc.bold(pc.red(`git sparse-checkout failed for ${source.remote}:`)));
|
|
60
|
+
console.error(err.stderr || err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
throw err;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const pulled = new Map<string, PulledLexicon>();
|
|
67
|
+
const pulled = new Map<string, PulledLexicon>();
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
for await (const filename of fs.glob(source.pattern, { cwd: cloneDir })) {
|
|
70
|
+
const absolute = path.join(cloneDir, filename);
|
|
71
|
+
const stat = await fs.stat(absolute);
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
if (!stat.isFile()) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
const location: SourceLocation = {
|
|
78
|
+
absolutePath: absolute,
|
|
79
|
+
relativePath: filename,
|
|
80
|
+
sourceDescription: source.remote,
|
|
81
|
+
};
|
|
81
82
|
|
|
82
|
-
|
|
83
|
+
const doc = await parseLexiconFile(location);
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
pulled.set(doc.id, { nsid: doc.id, doc, location });
|
|
86
|
+
}
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
let rev: string;
|
|
89
|
+
try {
|
|
90
|
+
const result = await runGit(['-C', cloneDir, 'rev-parse', 'HEAD'], { timeoutMs: 10_000 });
|
|
91
|
+
rev = result.stdout.trim();
|
|
92
|
+
} catch (err) {
|
|
93
|
+
if (err instanceof GitError) {
|
|
94
|
+
console.error(pc.bold(pc.red(`git rev-parse failed for ${source.remote}:`)));
|
|
95
|
+
console.error(err.stderr || err.message);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw err;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
return { pulled, rev };
|
|
103
|
+
} finally {
|
|
104
|
+
await fs.rm(tempParent, { recursive: true, force: true });
|
|
100
105
|
}
|
|
101
|
-
|
|
102
|
-
await fs.rm(tempParent, { recursive: true, force: true });
|
|
103
|
-
|
|
104
|
-
return { pulled, rev };
|
|
105
106
|
};
|
package/dist/shared-options.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const sharedOptions: import("@optique/core/parser").Parser<"sync", {
|
|
2
|
-
readonly config: string | undefined;
|
|
3
|
-
}, {
|
|
4
|
-
readonly config: [import("@optique/core/valueparser").ValueParserResult<string> | undefined] | undefined;
|
|
5
|
-
}>;
|
|
6
|
-
//# sourceMappingURL=shared-options.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared-options.d.ts","sourceRoot":"","sources":["../src/shared-options.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,aAAa;;;;EAMxB,CAAC"}
|
package/dist/shared-options.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
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
|
-
export const sharedOptions = object(`Global options`, {
|
|
7
|
-
config: optional(option('-c', '--config', pathParser({ metavar: 'CONFIG' }), {
|
|
8
|
-
description: message `path to the lexicon configuration file. defaults to searching for lex.config.js or lex.config.ts in the current directory.`,
|
|
9
|
-
})),
|
|
10
|
-
});
|
|
11
|
-
//# sourceMappingURL=shared-options.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shared-options.js","sourceRoot":"","sources":["../src/shared-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,EAAE;IACrD,MAAM,EAAE,QAAQ,CACf,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE;QAC3D,WAAW,EAAE,OAAO,CAAA,4HAA4H;KAChJ,CAAC,CACF;CACD,CAAC,CAAC"}
|
package/src/shared-options.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
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
|
-
});
|