a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
99
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(lex-cli): move generate configs over to `generate` field

Mary 4e73cfd7 f652050b

+246 -117
+5
.changeset/clever-falcons-repair.md
··· 1 + --- 2 + '@atcute/lex-cli': minor 3 + --- 4 + 5 + move generate configs over to `generate` field
+10 -6
packages/definitions/atproto/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + clean: true, 13 + }, 10 14 pull: { 11 15 outdir: 'lexicons/', 12 16 clean: true,
+11 -7
packages/definitions/bluemoji/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto', '@atcute/bluesky'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto', '@atcute/bluesky'], 13 + clean: true, 14 + }, 11 15 // pull: { 12 16 // outdir: 'lexicons/', 13 17 // clean: true,
+11 -6
packages/definitions/bluesky/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - imports: ['@atcute/atproto'], 9 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 10 15 pull: { 11 16 outdir: 'lexicons/', 12 17 clean: true,
+1 -1
packages/definitions/bluesky/package.json
··· 33 33 "pull": "lex-cli pull", 34 34 "test": "vitest", 35 35 "generate": "pnpm run generate:lexicons; pnpm run generate:limits", 36 - "generate:lexicons": "rm -r lib/lexicons/; lex-cli generate", 36 + "generate:lexicons": "lex-cli generate", 37 37 "generate:limits": "node scripts/generate-limits.js", 38 38 "prepublish": "rm -r dist; pnpm run build" 39 39 },
+11 -7
packages/definitions/frontpage/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+11 -7
packages/definitions/leaflet/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+11 -7
packages/definitions/lexicon-community/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+10 -5
packages/definitions/microcosm/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons-src/**/*.ts'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons-src/**/*.ts'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + clean: true, 13 + }, 9 14 export: { 10 15 outdir: 'lexicons/', 11 16 clean: true,
+11 -7
packages/definitions/ozone/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto', '@atcute/bluesky'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto', '@atcute/bluesky'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+11 -7
packages/definitions/pckt/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+11 -7
packages/definitions/standard-site/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+11 -7
packages/definitions/tangled/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - imports: ['@atcute/atproto'], 10 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + imports: ['@atcute/atproto'], 13 + clean: true, 14 + }, 11 15 pull: { 12 16 outdir: 'lexicons/', 13 17 clean: true,
+10 -6
packages/definitions/whitewind/lex.config.js
··· 1 1 import { defineLexiconConfig } from '@atcute/lex-cli'; 2 2 3 3 export default defineLexiconConfig({ 4 - files: ['lexicons/com/whtwnd/**/*.json'], 5 - outdir: 'lib/lexicons/', 6 - modules: { importSuffix: '.ts' }, 7 - formatter: { type: 'lsp', command: 'oxfmt --lsp' }, 8 - generate: { clean: true }, 9 - 4 + formatter: { 5 + type: 'lsp', 6 + command: 'oxfmt --lsp', 7 + }, 8 + generate: { 9 + files: ['lexicons/com/whtwnd/**/*.json'], 10 + outdir: 'lib/lexicons/', 11 + modules: { importSuffix: '.ts' }, 12 + clean: true, 13 + }, 10 14 pull: { 11 15 outdir: 'lexicons/', 12 16 clean: true,
+7 -2
packages/lexicons/lex-cli/src/commands/export.ts
··· 68 68 const config = await loadConfig(args.config); 69 69 const exportConfig = ensureExportConfig(config); 70 70 71 - // use export.files if specified, otherwise fall back to root files config 72 - const files = exportConfig.files ?? config.files; 71 + // use export.files if specified, otherwise fall back to generate.files 72 + const files = exportConfig.files ?? config.generate?.files; 73 + if (!files || files.length === 0) { 74 + console.error(pc.bold(pc.red(`export.files or generate.files must be specified`))); 75 + process.exit(1); 76 + } 77 + 73 78 const outdir = path.resolve(config.root, exportConfig.outdir); 74 79 const formatter = await createFormatter(config.formatter, config.root); 75 80
+28 -7
packages/lexicons/lex-cli/src/commands/generate.ts
··· 145 145 146 146 export type GenerateCommand = InferValue<typeof generateCommandSchema>; 147 147 148 - const ensureGenerateConfig = (config: NormalizedConfig): GenerateConfig => { 149 - return config.generate ?? {}; 148 + type ResolvedGenerateConfig = GenerateConfig & { outdir: string; files: string[] }; 149 + 150 + const ensureGenerateConfig = (config: NormalizedConfig): ResolvedGenerateConfig => { 151 + const generate = config.generate; 152 + if (!generate) { 153 + console.error(pc.bold(pc.red(`generate configuration missing`))); 154 + process.exit(1); 155 + } 156 + 157 + const { outdir, files } = generate; 158 + if (!outdir) { 159 + console.error(pc.bold(pc.red(`generate.outdir is required`))); 160 + process.exit(1); 161 + } 162 + 163 + if (!files || files.length === 0) { 164 + console.error(pc.bold(pc.red(`generate.files is required`))); 165 + process.exit(1); 166 + } 167 + 168 + return { ...generate, outdir, files }; 150 169 }; 151 170 152 171 /** ··· 158 177 const generateConfig = ensureGenerateConfig(config); 159 178 160 179 // resolve imports to mappings 161 - const importMappings = config.imports ? await resolveImportsToMappings(config.imports, config.root) : []; 162 - const allMappings = [...importMappings, ...(config.mappings ?? [])]; 180 + const importMappings = generateConfig.imports 181 + ? await resolveImportsToMappings(generateConfig.imports, config.root) 182 + : []; 183 + const allMappings = [...importMappings, ...(generateConfig.mappings ?? [])]; 163 184 164 185 // load lexicons from files 165 - const loaded = await loadLexicons(config.files, config.root); 186 + const loaded = await loadLexicons(generateConfig.files, config.root); 166 187 const documents = loaded.map((l) => l.doc); 167 188 168 - const outdir = path.join(config.root, config.outdir); 189 + const outdir = path.join(config.root, generateConfig.outdir); 169 190 const formatter = await createFormatter(config.formatter, config.root); 170 191 171 192 if (generateConfig.clean) { ··· 179 200 documents: documents, 180 201 mappings: allMappings, 181 202 modules: { 182 - importSuffix: config.modules?.importSuffix ?? '.js', 203 + importSuffix: generateConfig.modules?.importSuffix ?? '.js', 183 204 }, 184 205 })) { 185 206 const filename = path.join(outdir, file.filename);
+76 -28
packages/lexicons/lex-cli/src/config.ts
··· 79 79 }), 80 80 ); 81 81 82 - const generateConfigSchema = v.object({ 83 - clean: v.boolean().optional(), 84 - }); 85 - 86 - export type GitSourceConfig = v.Infer<typeof gitSourceConfigSchema>; 87 - export type AtprotoNsidsSourceConfig = v.Infer<typeof atprotoNsidsSourceConfigSchema>; 88 - export type AtprotoAuthoritySourceConfig = v.Infer<typeof atprotoAuthoritySourceConfigSchema>; 89 - export type AtprotoSourceConfig = v.Infer<typeof atprotoSourceConfigSchema>; 90 - export type SourceConfig = v.Infer<typeof sourceConfigSchema>; 91 - export type PullConfig = v.Infer<typeof pullConfigSchema>; 92 - export type ExportConfig = v.Infer<typeof exportConfigSchema>; 93 - export type FormatterConfig = v.Infer<typeof formatterConfigSchema>; 94 - export type GenerateConfig = v.Infer<typeof generateConfigSchema>; 95 - 96 82 const isValidLexiconPattern = (pattern: string): boolean => { 97 83 if (pattern.endsWith('.*')) { 98 84 return isNsid(`${pattern.slice(0, -2)}.x`); ··· 132 118 imports: mappingImports, 133 119 }); 134 120 135 - export const lexiconConfigSchema = v.object({ 136 - outdir: v.string().assert((value) => value.length > 0, `must not be empty`), 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(), 137 135 files: v 138 136 .array(v.string().assert((value) => value.length > 0, `must not be empty`)) 139 - .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(), 140 139 imports: v.array(v.string().assert((value) => value.length > 0, `must not be empty`)).optional(), 141 140 mappings: v.array(importMappingSchema).optional(), 142 - modules: v 143 - .object({ 144 - importSuffix: v 145 - .string() 146 - .assert((value) => value.length > 0, `must not be empty`) 147 - .optional(), 148 - }) 149 - .partial() 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`) 150 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(), 151 172 formatter: formatterConfigSchema.optional((): FormatterConfig => ({ type: 'prettier' })), 152 173 generate: generateConfigSchema.optional(), 153 174 pull: pullConfigSchema.optional(), ··· 156 177 157 178 export type LexiconConfig = v.Infer<typeof lexiconConfigSchema>; 158 179 159 - export interface NormalizedConfig extends LexiconConfig { 180 + export type NormalizedConfig = Omit< 181 + LexiconConfig, 182 + 'outdir' | 'files' | 'imports' | 'mappings' | 'modules' 183 + > & { 160 184 root: string; 161 - } 185 + }; 162 186 163 187 export const loadConfig = async (configPath?: string): Promise<NormalizedConfig> => { 164 188 let configFilename: string | undefined; ··· 213 237 process.exit(1); 214 238 } 215 239 216 - return { ...configResult.value, root: configDirname }; 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 }; 217 265 };