@saykit/config 0.0.0-beta-20260330102339 → 0.0.0-beta-20260418203312

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.
@@ -1,139 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from "node:module";
2
+ import { t as resolveConfig } from "../resolve-BifzXxrw.mjs";
3
+ import { t as generateHash } from "../hash-CA-PhXGF.mjs";
3
4
  import { Command, program } from "@commander-js/extra-typings";
4
- import { dirname, extname, join, relative, resolve } from "node:path";
5
- import picomatch from "picomatch";
6
- import * as z from "zod";
7
- import { access, glob, mkdir, readFile, rm, watch, writeFile } from "node:fs/promises";
8
- import { pathToFileURL } from "node:url";
5
+ import { dirname, join, relative, resolve } from "node:path";
9
6
  import { AsyncLocalStorage } from "node:async_hooks";
10
- import { collectMessages, generateHash } from "@saykit/babel-plugin/core";
11
-
12
- //#region src/shapes.ts
13
- const Message = z.object({
14
- message: z.string(),
15
- translation: z.string().optional(),
16
- id: z.string().optional(),
17
- context: z.string().optional(),
18
- comments: z.string().array(),
19
- references: z.string().array()
20
- });
21
- const Formatter = z.object({
22
- extension: z.templateLiteral([".", z.string()]),
23
- parse: z.custom((v) => typeof v === "function"),
24
- stringify: z.custom((v) => typeof v === "function")
25
- });
26
- const Bucket = z.object({
27
- include: z.array(z.string()),
28
- exclude: z.array(z.string()).optional(),
29
- output: z.templateLiteral([
30
- z.string(),
31
- "{locale}",
32
- z.string(),
33
- ".{extension}"
34
- ]),
35
- formatter: Formatter
36
- }).transform((v) => ({
37
- ...v,
38
- match: picomatch(v.include, { ignore: v.exclude })
39
- }));
40
- const Configuration = z.object({
41
- sourceLocale: z.string(),
42
- locales: z.tuple([z.string()], z.string()),
43
- fallbackLocales: z.record(z.string(), z.array(z.string())).optional(),
44
- buckets: z.array(Bucket)
45
- }).refine((c) => c.sourceLocale === c.locales[0], "sourceLocale must be the same as locales[0]");
46
-
47
- //#endregion
48
- //#region src/features/loader/explorer.ts
49
- function getFilesToTry(name) {
50
- return [
51
- `${name}.config.js`,
52
- `${name}.config.cjs`,
53
- `${name}.config.mjs`,
54
- `${name}.config.ts`,
55
- `${name}.config.mts`,
56
- `${name}.config.cts`
57
- ];
58
- }
59
- async function findConfigFile(moduleName, projectDir) {
60
- for (const fileName of getFilesToTry(moduleName)) try {
61
- const id = join(projectDir, fileName);
62
- await access(id);
63
- return {
64
- id,
65
- content: await readFile(id, "utf8")
66
- };
67
- } catch {}
68
- return null;
69
- }
70
-
71
- //#endregion
72
- //#region src/features/loader/loaders.ts
73
- const js = async (path, _content) => {
74
- try {
75
- const { href } = pathToFileURL(path);
76
- return (await import(href)).default;
77
- } catch (importError) {
78
- try {
79
- const require = globalThis.require ?? createRequire(path);
80
- const module = require(path);
81
- delete require.cache[require.resolve(path)];
82
- return module?.default ?? module;
83
- } catch (requireError) {
84
- throw new Error("Failed to import module", { cause: [importError, requireError] });
85
- }
86
- }
87
- };
88
- const ts = async (path, content) => {
89
- const ts = await import("typescript");
90
- const outputPath = `${path}.${Date.now()}.js`;
91
- try {
92
- const tsConfigPath = ts.findConfigFile(dirname(path), ts.sys.fileExists) || "tsconfig.json";
93
- const { config: tsConfig, error } = ts.readConfigFile(tsConfigPath, ts.sys.readFile);
94
- if (error) throw error;
95
- tsConfig.compilerOptions = {
96
- ...tsConfig.compilerOptions,
97
- module: ts.ModuleKind.ES2022,
98
- moduleResolution: ts.ModuleResolutionKind.Bundler,
99
- target: ts.ScriptTarget.ES2022,
100
- noEmit: false
101
- };
102
- const transpiledContent = ts.transpileModule(content, tsConfig).outputText;
103
- await writeFile(outputPath, transpiledContent);
104
- return await js(outputPath, transpiledContent);
105
- } catch (error) {
106
- throw new Error("Failed to import module", { cause: error });
107
- } finally {
108
- if (ts.sys.fileExists(outputPath)) await rm(outputPath);
109
- }
110
- };
111
- var loaders_default = Object.freeze({
112
- ".js": js,
113
- ".mjs": js,
114
- ".cjs": js,
115
- ".ts": ts,
116
- ".mts": ts,
117
- ".cts": ts
118
- });
119
-
120
- //#endregion
121
- //#region src/features/loader/resolve.ts
122
- async function useConfig(name = "saykit") {
123
- const file = await findConfigFile(name, process.cwd());
124
- if (!file) throw new Error(`Could not find config file for "${name}"`);
125
- const ext = extname(file.id).toLowerCase();
126
- const loader = ext in loaders_default ? loaders_default[ext] : null;
127
- if (!loader) throw new Error(`Unsupported config file type "${ext}" for "${name}"`);
128
- let config = await loader(file.id, file.content);
129
- if (!config || typeof config !== "object") throw new Error(`Invalid config file for "${name}"`);
130
- if (config && typeof config === "object" && "saykit" in config) config = config.saykit;
131
- const result = await Configuration.safeParseAsync(config);
132
- if (result.error) throw new Error(`Invalid config file for "${name}"`, { cause: result.error });
133
- return result.data;
134
- }
135
-
136
- //#endregion
7
+ import { glob, mkdir, readFile, watch, writeFile } from "node:fs/promises";
137
8
  //#region src/features/logger.ts
138
9
  const RESET = "\x1B[0m";
139
10
  const DIM = "\x1B[2m";
@@ -171,108 +42,7 @@ var Logger = class {
171
42
  if (this.#verbose) this.log(` ${DIM}→ ${message}${RESET}`);
172
43
  }
173
44
  };
174
- const loggerStorage = new AsyncLocalStorage({ defaultValue: new Logger() });
175
-
176
- //#endregion
177
- //#region src/features/extract.ts
178
- async function extractMessages(path) {
179
- return collectMessages(path, await readFile(path, "utf8").catch(() => "")).map((m) => ({
180
- message: m.toICUString(),
181
- translation: m.toICUString(),
182
- id: m.descriptor.id,
183
- context: m.descriptor.context,
184
- comments: m.comments,
185
- references: m.references.map((r) => relative(process.cwd(), r).replaceAll("\\", "/"))
186
- }));
187
- }
188
- function mergeUnique(...items) {
189
- return Array.from(new Set(items.flat()));
190
- }
191
- function mergeMessages(messages) {
192
- const mergedMessages = messages.reduce((map, message) => {
193
- const key = message.id ?? generateHash(message.message, message.context);
194
- const existing = map.get(key) ?? message;
195
- map.set(key, {
196
- ...existing,
197
- comments: mergeUnique(...existing.comments, ...message.comments),
198
- references: mergeUnique(...existing.references, ...message.references)
199
- });
200
- return map;
201
- }, /* @__PURE__ */ new Map());
202
- return Array.from(mergedMessages.values());
203
- }
204
- function reconcileMessages(existingMessages, newMessages) {
205
- const existingMessagesMap = existingMessages.reduce((map, message) => {
206
- const key = message.id ?? generateHash(message.message, message.context);
207
- map.set(key, message);
208
- return map;
209
- }, /* @__PURE__ */ new Map());
210
- const updatedMessagesMap = newMessages.reduce((map, message) => {
211
- const key = message.id ?? generateHash(message.message, message.context);
212
- const existingMessage = existingMessagesMap.get(key);
213
- map.set(key, {
214
- message: message.message,
215
- translation: void 0,
216
- ...existingMessage,
217
- id: message.id,
218
- context: message.context,
219
- comments: message.comments,
220
- references: message.references
221
- });
222
- return map;
223
- }, /* @__PURE__ */ new Map());
224
- return Array.from(updatedMessagesMap.values());
225
- }
226
- function expandOutputPath(bucket, locale, extension = bucket.formatter.extension) {
227
- return resolve(bucket.output.replaceAll("{locale}", locale).replaceAll("{extension}", extension.slice(1)));
228
- }
229
- async function readMessagesFromDisk(bucket, locale, path = expandOutputPath(bucket, locale)) {
230
- const content = await readFile(path, "utf8").catch(() => "");
231
- if (!content) return [];
232
- return await bucket.formatter.parse(content, { locale });
233
- }
234
- async function writeMessagesToDisk(bucket, locale, messages, path = expandOutputPath(bucket, locale)) {
235
- const content = await bucket.formatter.stringify(messages, { locale });
236
- await mkdir(dirname(path), { recursive: true });
237
- await writeFile(path, content);
238
- }
239
-
240
- //#endregion
241
- //#region src/features/compile.ts
242
- async function hydrateTranslations(cache, config, bucket, locale, messages) {
243
- if (cache.has(locale)) return cache.get(locale);
244
- const translations = await applyFallbackTranslations(cache, config, bucket, locale, messages);
245
- cache.set(locale, translations);
246
- return translations;
247
- }
248
- function getFallbackChain(config, locale) {
249
- return [...config.fallbackLocales?.[locale] ?? [], config.sourceLocale];
250
- }
251
- async function applyFallbackTranslations(cache, config, bucket, locale, messages) {
252
- const fallbacks = getFallbackChain(config, locale);
253
- const translations = {};
254
- for (const message of messages) {
255
- const key = message.id ?? generateHash(message.message, message.context);
256
- if (message.translation) {
257
- translations[key] = message.translation;
258
- continue;
259
- }
260
- for (const fallback of fallbacks) {
261
- const fallbackMessages = await hydrateTranslations(cache, config, bucket, fallback, messages);
262
- if (fallbackMessages[key]) {
263
- translations[key] = fallbackMessages[key];
264
- break;
265
- }
266
- }
267
- }
268
- return translations;
269
- }
270
- async function writeTranslationsToDisk(bucket, locale, translations, path = expandOutputPath(bucket, locale, ".json")) {
271
- const content = JSON.stringify(translations, null, 2);
272
- await mkdir(dirname(path), { recursive: true });
273
- await writeFile(path, content);
274
- }
275
-
45
+ new AsyncLocalStorage({ defaultValue: new Logger() });
276
46
  //#endregion
277
47
  //#region src/features/watch.ts
278
48
  /**
@@ -316,10 +86,61 @@ async function* watchDebounced(path, options, delay = 300) {
316
86
  yield next;
317
87
  } else await new Promise((r) => setTimeout(r, 10));
318
88
  }
319
-
320
89
  //#endregion
321
- //#region src/features/worker.ts
322
- function normalisePath(path) {
90
+ //#region src/features/catalogue/path.ts
91
+ function expandBucketOutputPath(bucket, locale, extension = bucket.formatter.extension) {
92
+ return resolve(bucket.output.replaceAll("{locale}", locale).replaceAll("{extension}", extension.slice(1)));
93
+ }
94
+ //#endregion
95
+ //#region src/features/catalogue/storage.ts
96
+ async function readCatalogueMessages(bucket, locale, path = expandBucketOutputPath(bucket, locale)) {
97
+ const content = await readFile(path, "utf8").catch(() => "");
98
+ if (!content) return [];
99
+ return bucket.formatter.parse(content, { locale });
100
+ }
101
+ async function writeCatalogueMessages(bucket, locale, messages, path = expandBucketOutputPath(bucket, locale)) {
102
+ const content = bucket.formatter.stringify(messages, { locale });
103
+ await mkdir(dirname(path), { recursive: true });
104
+ await writeFile(path, content);
105
+ }
106
+ //#endregion
107
+ //#region src/features/runtime/translations.ts
108
+ function getFallbackLocaleChain(config, locale) {
109
+ return [...config.fallbackLocales?.[locale] ?? [], config.sourceLocale];
110
+ }
111
+ async function hydrateTranslations(cache, config, bucket, locale, messages) {
112
+ if (cache.has(locale)) return cache.get(locale);
113
+ const translations = await applyFallbackTranslations(cache, config, bucket, locale, messages);
114
+ cache.set(locale, translations);
115
+ return translations;
116
+ }
117
+ async function applyFallbackTranslations(cache, config, bucket, locale, messages) {
118
+ const fallbackLocales = getFallbackLocaleChain(config, locale);
119
+ const translations = {};
120
+ for (const message of messages) {
121
+ const key = message.id ?? generateHash(message.message, message.context);
122
+ if (message.translation) {
123
+ translations[key] = message.translation;
124
+ continue;
125
+ }
126
+ for (const fallbackLocale of fallbackLocales) {
127
+ const fallbackTranslations = await hydrateTranslations(cache, config, bucket, fallbackLocale, await readCatalogueMessages(bucket, fallbackLocale));
128
+ if (fallbackTranslations[key]) {
129
+ translations[key] = fallbackTranslations[key];
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ return translations;
135
+ }
136
+ async function writeRuntimeTranslations(bucket, locale, translations, path = expandBucketOutputPath(bucket, locale, ".json")) {
137
+ const content = JSON.stringify(translations, null, 2);
138
+ await mkdir(dirname(path), { recursive: true });
139
+ await writeFile(path, content);
140
+ }
141
+ //#endregion
142
+ //#region src/features/workers/shared.ts
143
+ function normalisePathForLogs(path) {
323
144
  return relative(process.cwd(), path).replaceAll("\\", "/");
324
145
  }
325
146
  var BucketWorker = class {
@@ -332,66 +153,137 @@ var BucketWorker = class {
332
153
  this.logger = logger;
333
154
  }
334
155
  };
156
+ //#endregion
157
+ //#region src/features/workers/compile-worker.ts
158
+ var BucketCompileWorker = class extends BucketWorker {
159
+ #translationsByLocale = /* @__PURE__ */ new Map();
160
+ async compileAll() {
161
+ this.logger.info(`Compiling bucket: ${this.bucket.include}`);
162
+ for (const locale of this.config.locales) await this.compileLocale(locale);
163
+ this.logger.success(`Compilation complete for bucket: ${this.bucket.include}`);
164
+ }
165
+ async compileLocale(locale) {
166
+ this.logger.step(`Compiling locale: ${locale}`);
167
+ const messages = await readCatalogueMessages(this.bucket, locale);
168
+ const translations = await hydrateTranslations(this.#translationsByLocale, this.config, this.bucket, locale, messages);
169
+ this.logger.step(`Writing runtime file for ${locale}`);
170
+ await writeRuntimeTranslations(this.bucket, locale, translations);
171
+ }
172
+ };
173
+ //#endregion
174
+ //#region src/features/catalogue/extractor.ts
175
+ async function extractMessagesFromFile(path, bucket) {
176
+ const content = await readFile(path, "utf8").catch(() => "");
177
+ if (!content) return [];
178
+ return bucket.transformer.extract(content, path).map((message) => ({
179
+ ...message,
180
+ translation: message.translation ?? message.message,
181
+ references: message.references.map((reference) => relative(process.cwd(), reference).replaceAll("\\", "/"))
182
+ }));
183
+ }
184
+ //#endregion
185
+ //#region src/features/catalogue/merge.ts
186
+ function mergeUnique(...items) {
187
+ return Array.from(new Set(items.flat()));
188
+ }
189
+ function getMessageKey(message) {
190
+ return message.id ?? generateHash(message.message, message.context);
191
+ }
192
+ function mergeExtractedMessages(messages) {
193
+ const mergedMessages = messages.reduce((map, message) => {
194
+ const key = getMessageKey(message);
195
+ const existing = map.get(key) ?? message;
196
+ map.set(key, {
197
+ ...existing,
198
+ comments: mergeUnique(...existing.comments, ...message.comments),
199
+ references: mergeUnique(...existing.references, ...message.references)
200
+ });
201
+ return map;
202
+ }, /* @__PURE__ */ new Map());
203
+ return Array.from(mergedMessages.values());
204
+ }
205
+ function reconcileLocaleMessages(existingMessages, nextMessages) {
206
+ const existingMessagesByKey = existingMessages.reduce((map, message) => {
207
+ map.set(getMessageKey(message), message);
208
+ return map;
209
+ }, /* @__PURE__ */ new Map());
210
+ const reconciledMessages = nextMessages.reduce((map, message) => {
211
+ const key = getMessageKey(message);
212
+ const existingMessage = existingMessagesByKey.get(key);
213
+ map.set(key, {
214
+ message: message.message,
215
+ translation: void 0,
216
+ ...existingMessage,
217
+ id: message.id,
218
+ context: message.context,
219
+ comments: message.comments,
220
+ references: message.references
221
+ });
222
+ return map;
223
+ }, /* @__PURE__ */ new Map());
224
+ return Array.from(reconciledMessages.values());
225
+ }
226
+ //#endregion
227
+ //#region src/features/workers/extract-worker.ts
335
228
  var BucketExtractWorker = class extends BucketWorker {
336
- index = /* @__PURE__ */ new Map();
229
+ #indexedMessagesByPath = /* @__PURE__ */ new Map();
337
230
  get messages() {
338
- return Array.from(this.index.values()).flat();
231
+ return Array.from(this.#indexedMessagesByPath.values()).flat();
339
232
  }
340
- async indexPath(path) {
341
- const rp = normalisePath(path);
342
- this.logger.step(`Processing ${rp}`);
343
- const messages = await extractMessages(path);
344
- if (!messages.length) return false;
345
- this.index.set(path, messages);
346
- this.logger.step(`Found ${messages.length} messages(s) in ${rp}`);
233
+ async #indexPath(path) {
234
+ const relativePath = normalisePathForLogs(path);
235
+ this.logger.step(`Processing ${relativePath}`);
236
+ const messages = await extractMessagesFromFile(path, this.bucket);
237
+ if (!messages.length) {
238
+ if (this.#indexedMessagesByPath.has(path)) {
239
+ this.#indexedMessagesByPath.delete(path);
240
+ this.logger.step(`Removed stale entries for ${relativePath}`);
241
+ return true;
242
+ }
243
+ return false;
244
+ }
245
+ this.#indexedMessagesByPath.set(path, messages);
246
+ this.logger.step(`Found ${messages.length} message(s) in ${relativePath}`);
347
247
  return true;
348
248
  }
349
249
  async scanAll() {
350
250
  this.logger.info(`Scanning bucket: ${this.bucket.include}`);
351
251
  const paths = await globBucket(this.bucket);
352
252
  this.logger.step(`Found ${paths.length} file(s)`);
353
- await Promise.all(paths.map((p) => this.indexPath(p)));
253
+ await Promise.all(paths.map((path) => this.#indexPath(path)));
354
254
  this.logger.info(`Total extracted messages: ${this.messages.length}`);
355
255
  }
356
256
  async writeAll() {
357
- const newMessages = mergeMessages(this.messages);
358
- this.logger.info(`Writing ${newMessages.length} messages to locales`);
257
+ const mergedMessages = mergeExtractedMessages(this.messages);
258
+ this.logger.info(`Writing ${mergedMessages.length} messages to locales`);
359
259
  for (const locale of this.config.locales) {
360
260
  this.logger.step(`Writing locale file for ${locale} to disk`);
361
- const existingMessages = await readMessagesFromDisk(this.bucket, locale);
362
- const updatedMessages = locale === this.config.sourceLocale ? newMessages : reconcileMessages(existingMessages, newMessages);
363
- await writeMessagesToDisk(this.bucket, locale, updatedMessages);
261
+ const existingMessages = await readCatalogueMessages(this.bucket, locale);
262
+ const nextMessages = locale === this.config.sourceLocale ? mergedMessages : reconcileLocaleMessages(existingMessages, mergedMessages);
263
+ await writeCatalogueMessages(this.bucket, locale, nextMessages);
364
264
  }
365
265
  this.logger.success(`Extraction complete for bucket: ${this.bucket.include}`);
366
266
  }
367
267
  async updatePath(path) {
368
- const changed = await this.indexPath(path);
268
+ const changed = await this.#indexPath(path);
369
269
  if (changed) await this.writeAll();
370
270
  return changed;
371
271
  }
372
272
  };
373
- var BucketCompileWorker = class extends BucketWorker {
374
- cache = /* @__PURE__ */ new Map();
375
- async compileAll() {
376
- this.logger.info(`Compiling bucket: ${this.bucket.include}`);
377
- for (const locale of this.config.locales) await this.compileLocale(locale);
378
- this.logger.success(`Compilation complete for bucket: ${this.bucket.include}`);
379
- }
380
- async compileLocale(locale) {
381
- this.logger.step(`Compiling locale: ${locale}`);
382
- const messages = await readMessagesFromDisk(this.bucket, locale);
383
- const translations = await hydrateTranslations(this.cache, this.config, this.bucket, locale, messages);
384
- this.logger.step(`Writing runtime file for ${locale}`);
385
- await writeTranslationsToDisk(this.bucket, locale, translations);
386
- }
387
- };
273
+ //#endregion
274
+ //#region src/features/workers/build-worker.ts
388
275
  var BucketBuildWorker = class extends BucketWorker {
389
276
  extract;
390
277
  compile;
391
278
  constructor(config, bucket, logger) {
392
- super(config, bucket, logger);
393
- this.extract = new BucketExtractWorker(config, bucket, logger);
394
- this.compile = new BucketCompileWorker(config, bucket, logger);
279
+ const parameters = [
280
+ config,
281
+ bucket,
282
+ logger
283
+ ];
284
+ super(...parameters);
285
+ this.extract = new BucketExtractWorker(...parameters);
286
+ this.compile = new BucketCompileWorker(...parameters);
395
287
  }
396
288
  async buildAll() {
397
289
  await this.extract.scanAll();
@@ -404,41 +296,38 @@ var BucketBuildWorker = class extends BucketWorker {
404
296
  if (!event.filename || !this.bucket.match(event.filename)) continue;
405
297
  const filePath = join(process.cwd(), event.filename);
406
298
  if (await this.extract.updatePath(filePath)) {
407
- this.logger.info(`Recompiling due to changes in ${normalisePath(filePath)}`);
299
+ this.logger.info(`Recompiling due to changes in ${normalisePathForLogs(filePath)}`);
408
300
  await this.compile.compileAll();
409
301
  }
410
302
  }
411
303
  }
412
304
  };
413
-
414
305
  //#endregion
415
306
  //#region src/commands/build.ts
416
307
  var build_default = new Command().name("build").description("").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
417
- const config = await useConfig("saykit");
308
+ const config = await resolveConfig("saykit");
418
309
  const logger = new Logger(options);
419
310
  logger.header("🏗 Building Messages");
420
311
  const tasks = config.buckets.map(async (bucket) => {
421
312
  await new BucketBuildWorker(config, bucket, logger).buildAll();
422
313
  });
423
- await Promise.allSettled(tasks);
314
+ await Promise.all(tasks);
424
315
  });
425
-
426
316
  //#endregion
427
317
  //#region src/commands/compile.ts
428
318
  var compile_default = new Command("compile").description("Compile translations into runtime-ready locale files").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
429
- const config = await useConfig("saykit");
319
+ const config = await resolveConfig("saykit");
430
320
  const logger = new Logger(options);
431
321
  logger.header("🛠 Compiling Translations");
432
322
  const tasks = config.buckets.map(async (bucket) => {
433
323
  await new BucketCompileWorker(config, bucket, logger).compileAll();
434
324
  });
435
- await Promise.allSettled(tasks);
325
+ await Promise.all(tasks);
436
326
  });
437
-
438
327
  //#endregion
439
328
  //#region src/commands/extract.ts
440
329
  var extract_default = new Command("extract").description("Extract messages from source files").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
441
- const config = await useConfig("saykit");
330
+ const config = await resolveConfig("saykit");
442
331
  const logger = new Logger(options);
443
332
  logger.header("🛠 Extracting Messages");
444
333
  const tasks = config.buckets.map(async (bucket) => {
@@ -446,13 +335,14 @@ var extract_default = new Command("extract").description("Extract messages from
446
335
  await worker.scanAll();
447
336
  await worker.writeAll();
448
337
  });
449
- await Promise.allSettled(tasks);
338
+ const rejections = (await Promise.allSettled(tasks)).filter((r) => r.status === "rejected");
339
+ if (rejections.length > 0) {
340
+ const errors = rejections.map((r) => r.reason).join("\n");
341
+ throw new Error(`Bucket extraction failed:\n${errors}`);
342
+ }
450
343
  });
451
-
452
344
  //#endregion
453
345
  //#region src/commands/index.ts
454
346
  program.name("saykit").helpOption("-h, --help", "Display help for command").helpCommand("help [command]", "Display help for command").addCommand(extract_default).addCommand(compile_default).addCommand(build_default).parse();
455
-
456
347
  //#endregion
457
- export { };
458
- //# sourceMappingURL=index.mjs.map
348
+ export {};
@@ -0,0 +1,37 @@
1
+ import { i as Message } from "../../shapes-B0roKIQa.mjs";
2
+
3
+ //#region src/features/loader/resolve.d.ts
4
+ declare function resolveConfig(name?: string): {
5
+ sourceLocale: string;
6
+ locales: [string, ...string[]];
7
+ buckets: {
8
+ match: (id: string) => boolean;
9
+ include: string[];
10
+ output: `${string}{locale}${string}.{extension}`;
11
+ formatter: {
12
+ extension: `.${string}`;
13
+ parse: (content: string, context: {
14
+ locale: string;
15
+ }) => Message[];
16
+ stringify: (messages: Message[], context: {
17
+ locale: string;
18
+ }) => string;
19
+ };
20
+ transformer: {
21
+ match: (id: string) => boolean;
22
+ extract: (code: string, id: string) => {
23
+ message: string;
24
+ comments: string[];
25
+ references: string[];
26
+ translation?: string | undefined;
27
+ id?: string | undefined;
28
+ context?: string | undefined;
29
+ }[];
30
+ transform: (code: string, id: string) => string;
31
+ };
32
+ exclude?: string[] | undefined;
33
+ }[];
34
+ fallbackLocales?: Record<string, string[]> | undefined;
35
+ };
36
+ //#endregion
37
+ export { resolveConfig };
@@ -0,0 +1,2 @@
1
+ import { t as resolveConfig } from "../../resolve-BifzXxrw.mjs";
2
+ export { resolveConfig };
@@ -0,0 +1,62 @@
1
+ //#region src/features/messages/identifier.d.ts
2
+ declare const AUTO_INCREMENT_IDENTIFIER: unique symbol;
3
+ declare function assignSequenceIdentifiers(message: Message, sequence?: {
4
+ current: number;
5
+ }): void;
6
+ //#endregion
7
+ //#region src/features/messages/types.d.ts
8
+ declare abstract class Base {
9
+ toICUString(this: Message): string;
10
+ toHashString(this: Message): string;
11
+ }
12
+ declare class LiteralMessage extends Base {
13
+ readonly text: string;
14
+ constructor(text: string);
15
+ }
16
+ declare class ArgumentMessage extends Base {
17
+ identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
18
+ readonly expression: any;
19
+ constructor(identifier: string | typeof AUTO_INCREMENT_IDENTIFIER, expression: any);
20
+ }
21
+ declare class ElementMessage extends Base {
22
+ identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
23
+ readonly children: Message[];
24
+ readonly expression: any;
25
+ constructor(identifier: string | typeof AUTO_INCREMENT_IDENTIFIER, children: Message[], expression: any);
26
+ }
27
+ declare class ChoiceMessage extends Base {
28
+ readonly kind: string;
29
+ identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
30
+ readonly branches: {
31
+ identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
32
+ readonly value: Message;
33
+ }[];
34
+ readonly expression: any;
35
+ constructor(kind: string, identifier: string | typeof AUTO_INCREMENT_IDENTIFIER, branches: {
36
+ identifier: string | typeof AUTO_INCREMENT_IDENTIFIER;
37
+ readonly value: Message;
38
+ }[], expression: any);
39
+ }
40
+ declare class CompositeMessage extends Base {
41
+ readonly descriptor: {
42
+ id?: string;
43
+ context?: string;
44
+ };
45
+ readonly comments: string[];
46
+ readonly references: string[];
47
+ readonly children: Message[];
48
+ readonly accessor: any;
49
+ constructor(descriptor: {
50
+ id?: string;
51
+ context?: string;
52
+ }, comments: string[], references: string[], children: Message[], accessor: any);
53
+ }
54
+ type Message = LiteralMessage | ArgumentMessage | ElementMessage | ChoiceMessage | CompositeMessage;
55
+ //#endregion
56
+ //#region src/features/messages/convert.d.ts
57
+ declare function convertMessageToIcu(message: Message): string;
58
+ //#endregion
59
+ //#region src/features/messages/hash.d.ts
60
+ declare function generateHash(input: string, context?: string): string;
61
+ //#endregion
62
+ export { AUTO_INCREMENT_IDENTIFIER, ArgumentMessage, ChoiceMessage, CompositeMessage, ElementMessage, LiteralMessage, Message, assignSequenceIdentifiers, convertMessageToIcu, generateHash };