@saykit/config 0.0.0-beta-20260720032009 → 0.0.0-beta-20260720035025

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/README.md CHANGED
@@ -43,7 +43,7 @@ export default defineConfig({
43
43
  ```sh
44
44
  saykit extract # extract messages once
45
45
  saykit extract --watch # extract and watch for changes
46
- saykit clean # reconcile other locales against the source
46
+ saykit clean # prune dead entries from other locales
47
47
  ```
48
48
 
49
49
  Extraction only writes the **source** locale (the first entry in `locales`). Locales that don't
@@ -54,10 +54,9 @@ At load time (via the unplugin or Babel plugin), each locale module is filled fr
54
54
  chain, so an untranslated key resolves to a fallback locale and ultimately the source string — the
55
55
  runtime still loads a single locale.
56
56
 
57
- `saykit clean` reconciles every non-source locale against the current source catalogue: it adds
58
- missing keys (untranslated), drops entries that no longer exist in the source, and preserves any
59
- existing translations. Use it when you want to propagate source changes into locale files yourself
60
- rather than leaving it to your TMS.
57
+ `saykit clean` only ever subtracts from non-source locales: it drops entries that no longer exist in
58
+ the source catalogue and entries with an empty translation, and leaves everything else exactly as it
59
+ is. It never adds source keys to a locale file, that stays your TMS's job.
61
60
 
62
61
  ## Documentation
63
62
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  require("../index.cjs");
3
- const require_storage = require("../storage-CGt6RCnp.cjs");
3
+ const require_storage = require("../storage-C4rOvLGi.cjs");
4
4
  const require_loader = require("../loader-B25O-vF6.cjs");
5
5
  let _commander_js_extra_typings = require("@commander-js/extra-typings");
6
6
  let node_fs_promises = require("node:fs/promises");
@@ -46,17 +46,20 @@ var Logger = class {
46
46
  new node_async_hooks.AsyncLocalStorage({ defaultValue: new Logger() });
47
47
  //#endregion
48
48
  //#region src/commands/clean.ts
49
- var clean_default = new _commander_js_extra_typings.Command("clean").description("Reconcile non-source locale files against the source locale").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
49
+ var clean_default = new _commander_js_extra_typings.Command("clean").description("Remove orphaned and untranslated entries from non-source locale files").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
50
50
  const config = require_loader.resolveConfig();
51
51
  const logger = new Logger(options);
52
52
  logger.header("🧹 Cleaning Locales");
53
53
  const [sourceLocale, ...otherLocales] = config.locales;
54
54
  for (const bucket of config.buckets) {
55
55
  const sourceMessages = await require_storage.readCatalogueMessages(bucket, sourceLocale);
56
- logger.info(`Reconciling ${otherLocales.length} locale(s) against ${sourceLocale}`);
56
+ logger.info(`Cleaning ${otherLocales.length} locale(s) against ${sourceLocale}`);
57
57
  for (const locale of otherLocales) {
58
- logger.step(`Reconciling ${locale}`);
59
- await require_storage.writeCatalogueMessages(bucket, locale, require_storage.reconcileLocaleMessages(await require_storage.readCatalogueMessages(bucket, locale), sourceMessages));
58
+ logger.step(`Cleaning ${locale}`);
59
+ const existingMessages = await require_storage.readCatalogueMessages(bucket, locale);
60
+ const prunedMessages = require_storage.pruneLocaleMessages(existingMessages, sourceMessages);
61
+ logger.step(`Removed ${existingMessages.length - prunedMessages.length} entries from ${locale}`);
62
+ await require_storage.writeCatalogueMessages(bucket, locale, prunedMessages);
60
63
  }
61
64
  }
62
65
  logger.success("Locales cleaned");
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as mergeExtractedMessages, i as expandBucketOutputPath, n as writeCatalogueMessages, o as reconcileLocaleMessages, t as readCatalogueMessages } from "../storage-_WyCYi6d.mjs";
2
+ import { a as mergeExtractedMessages, i as expandBucketOutputPath, n as writeCatalogueMessages, o as pruneLocaleMessages, t as readCatalogueMessages } from "../storage-CqKPYfCR.mjs";
3
3
  import { t as resolveConfig } from "../loader-C2eolE_1.mjs";
4
4
  import { Command, program } from "@commander-js/extra-typings";
5
5
  import { access, glob, readFile, watch } from "node:fs/promises";
@@ -45,17 +45,20 @@ var Logger = class {
45
45
  new AsyncLocalStorage({ defaultValue: new Logger() });
46
46
  //#endregion
47
47
  //#region src/commands/clean.ts
48
- var clean_default = new Command("clean").description("Reconcile non-source locale files against the source locale").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
48
+ var clean_default = new Command("clean").description("Remove orphaned and untranslated entries from non-source locale files").option("-v, --verbose", "enable verbose logging", false).option("-q, --quiet", "suppress all logging", false).action(async (options) => {
49
49
  const config = resolveConfig();
50
50
  const logger = new Logger(options);
51
51
  logger.header("🧹 Cleaning Locales");
52
52
  const [sourceLocale, ...otherLocales] = config.locales;
53
53
  for (const bucket of config.buckets) {
54
54
  const sourceMessages = await readCatalogueMessages(bucket, sourceLocale);
55
- logger.info(`Reconciling ${otherLocales.length} locale(s) against ${sourceLocale}`);
55
+ logger.info(`Cleaning ${otherLocales.length} locale(s) against ${sourceLocale}`);
56
56
  for (const locale of otherLocales) {
57
- logger.step(`Reconciling ${locale}`);
58
- await writeCatalogueMessages(bucket, locale, reconcileLocaleMessages(await readCatalogueMessages(bucket, locale), sourceMessages));
57
+ logger.step(`Cleaning ${locale}`);
58
+ const existingMessages = await readCatalogueMessages(bucket, locale);
59
+ const prunedMessages = pruneLocaleMessages(existingMessages, sourceMessages);
60
+ logger.step(`Removed ${existingMessages.length - prunedMessages.length} entries from ${locale}`);
61
+ await writeCatalogueMessages(bucket, locale, prunedMessages);
59
62
  }
60
63
  }
61
64
  logger.success("Locales cleaned");
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  require("../../index.cjs");
3
3
  const require_hash = require("../../hash-8It7TJpB.cjs");
4
- const require_storage = require("../../storage-CGt6RCnp.cjs");
4
+ const require_storage = require("../../storage-C4rOvLGi.cjs");
5
5
  let node_path = require("node:path");
6
6
  //#region src/features/catalogue/record.ts
7
7
  /**
@@ -58,8 +58,8 @@ exports.assembleCatalogueRecord = assembleCatalogueRecord;
58
58
  exports.declarationPathFor = require_storage.declarationPathFor;
59
59
  exports.expandBucketOutputPath = require_storage.expandBucketOutputPath;
60
60
  exports.mergeExtractedMessages = require_storage.mergeExtractedMessages;
61
+ exports.pruneLocaleMessages = require_storage.pruneLocaleMessages;
61
62
  exports.readCatalogueMessages = require_storage.readCatalogueMessages;
62
- exports.reconcileLocaleMessages = require_storage.reconcileLocaleMessages;
63
63
  exports.resolveCatalogueSources = resolveCatalogueSources;
64
64
  exports.resolveFallbackChain = resolveFallbackChain;
65
65
  exports.writeCatalogueMessages = require_storage.writeCatalogueMessages;
@@ -9,7 +9,7 @@ declare function mergeExtractedMessages(messages: Message[]): {
9
9
  id?: string | undefined;
10
10
  context?: string | undefined;
11
11
  }[];
12
- declare function reconcileLocaleMessages(existingMessages: Message[], nextMessages: Message[]): {
12
+ declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
13
13
  message: string;
14
14
  comments: string[];
15
15
  references: string[];
@@ -65,4 +65,4 @@ declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: st
65
65
  }[]>;
66
66
  declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
67
67
  //#endregion
68
- export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, readCatalogueMessages, reconcileLocaleMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
68
+ export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
@@ -9,7 +9,7 @@ declare function mergeExtractedMessages(messages: Message[]): {
9
9
  id?: string | undefined;
10
10
  context?: string | undefined;
11
11
  }[];
12
- declare function reconcileLocaleMessages(existingMessages: Message[], nextMessages: Message[]): {
12
+ declare function pruneLocaleMessages(existingMessages: Message[], sourceMessages: Message[]): {
13
13
  message: string;
14
14
  comments: string[];
15
15
  references: string[];
@@ -65,4 +65,4 @@ declare function readCatalogueMessages(bucket: Bucket, locale: string, path?: st
65
65
  }[]>;
66
66
  declare function writeCatalogueMessages(bucket: Bucket, locale: string, messages: Message[], path?: string): Promise<void>;
67
67
  //#endregion
68
- export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, readCatalogueMessages, reconcileLocaleMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
68
+ export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
@@ -1,5 +1,5 @@
1
1
  import { t as generateHash } from "../../hash-DyC8GzMa.mjs";
2
- import { a as mergeExtractedMessages, i as expandBucketOutputPath, n as writeCatalogueMessages, o as reconcileLocaleMessages, r as declarationPathFor, t as readCatalogueMessages } from "../../storage-_WyCYi6d.mjs";
2
+ import { a as mergeExtractedMessages, i as expandBucketOutputPath, n as writeCatalogueMessages, o as pruneLocaleMessages, r as declarationPathFor, t as readCatalogueMessages } from "../../storage-CqKPYfCR.mjs";
3
3
  import { resolve } from "node:path";
4
4
  //#region src/features/catalogue/record.ts
5
5
  /**
@@ -52,4 +52,4 @@ function assembleCatalogueRecord(bucket, contents) {
52
52
  return record;
53
53
  }
54
54
  //#endregion
55
- export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, readCatalogueMessages, reconcileLocaleMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
55
+ export { assembleCatalogueRecord, declarationPathFor, expandBucketOutputPath, mergeExtractedMessages, pruneLocaleMessages, readCatalogueMessages, resolveCatalogueSources, resolveFallbackChain, writeCatalogueMessages };
@@ -22,21 +22,9 @@ function mergeExtractedMessages(messages) {
22
22
  }, /* @__PURE__ */ new Map());
23
23
  return Array.from(mergedMessages.values());
24
24
  }
25
- function reconcileLocaleMessages(existingMessages, nextMessages) {
26
- const existingMessagesByKey = existingMessages.reduce((map, message) => {
27
- map.set(getMessageKey(message), message);
28
- return map;
29
- }, /* @__PURE__ */ new Map());
30
- const reconciledMessages = nextMessages.reduce((map, message) => {
31
- const key = getMessageKey(message);
32
- const existingMessage = existingMessagesByKey.get(key);
33
- map.set(key, {
34
- ...message,
35
- translation: existingMessage?.translation
36
- });
37
- return map;
38
- }, /* @__PURE__ */ new Map());
39
- return Array.from(reconciledMessages.values());
25
+ function pruneLocaleMessages(existingMessages, sourceMessages) {
26
+ const sourceKeys = new Set(sourceMessages.map(getMessageKey));
27
+ return existingMessages.filter((message) => sourceKeys.has(getMessageKey(message)) && Boolean(message.translation));
40
28
  }
41
29
  //#endregion
42
30
  //#region src/features/catalogue/path.ts
@@ -60,7 +48,7 @@ function declarationPathFor(cataloguePath) {
60
48
  const DECLARATION_CONTENT = `
61
49
  declare const messages: Record<string, string>;
62
50
  export default messages;
63
- `.trim();
51
+ `.trimStart();
64
52
  async function readCatalogueMessages(bucket, locale, path = expandBucketOutputPath(bucket, locale)) {
65
53
  const content = await (0, node_fs_promises.readFile)(path, "utf8").catch(() => "");
66
54
  if (!content) return [];
@@ -95,16 +83,16 @@ Object.defineProperty(exports, "mergeExtractedMessages", {
95
83
  return mergeExtractedMessages;
96
84
  }
97
85
  });
98
- Object.defineProperty(exports, "readCatalogueMessages", {
86
+ Object.defineProperty(exports, "pruneLocaleMessages", {
99
87
  enumerable: true,
100
88
  get: function() {
101
- return readCatalogueMessages;
89
+ return pruneLocaleMessages;
102
90
  }
103
91
  });
104
- Object.defineProperty(exports, "reconcileLocaleMessages", {
92
+ Object.defineProperty(exports, "readCatalogueMessages", {
105
93
  enumerable: true,
106
94
  get: function() {
107
- return reconcileLocaleMessages;
95
+ return readCatalogueMessages;
108
96
  }
109
97
  });
110
98
  Object.defineProperty(exports, "writeCatalogueMessages", {
@@ -21,21 +21,9 @@ function mergeExtractedMessages(messages) {
21
21
  }, /* @__PURE__ */ new Map());
22
22
  return Array.from(mergedMessages.values());
23
23
  }
24
- function reconcileLocaleMessages(existingMessages, nextMessages) {
25
- const existingMessagesByKey = existingMessages.reduce((map, message) => {
26
- map.set(getMessageKey(message), message);
27
- return map;
28
- }, /* @__PURE__ */ new Map());
29
- const reconciledMessages = nextMessages.reduce((map, message) => {
30
- const key = getMessageKey(message);
31
- const existingMessage = existingMessagesByKey.get(key);
32
- map.set(key, {
33
- ...message,
34
- translation: existingMessage?.translation
35
- });
36
- return map;
37
- }, /* @__PURE__ */ new Map());
38
- return Array.from(reconciledMessages.values());
24
+ function pruneLocaleMessages(existingMessages, sourceMessages) {
25
+ const sourceKeys = new Set(sourceMessages.map(getMessageKey));
26
+ return existingMessages.filter((message) => sourceKeys.has(getMessageKey(message)) && Boolean(message.translation));
39
27
  }
40
28
  //#endregion
41
29
  //#region src/features/catalogue/path.ts
@@ -59,7 +47,7 @@ function declarationPathFor(cataloguePath) {
59
47
  const DECLARATION_CONTENT = `
60
48
  declare const messages: Record<string, string>;
61
49
  export default messages;
62
- `.trim();
50
+ `.trimStart();
63
51
  async function readCatalogueMessages(bucket, locale, path = expandBucketOutputPath(bucket, locale)) {
64
52
  const content = await readFile(path, "utf8").catch(() => "");
65
53
  if (!content) return [];
@@ -76,4 +64,4 @@ async function writeCatalogueMessages(bucket, locale, messages, path = expandBuc
76
64
  await Promise.all([writeFile(path, catalogueContent), writeFile(declarationPath, DECLARATION_CONTENT)]);
77
65
  }
78
66
  //#endregion
79
- export { mergeExtractedMessages as a, expandBucketOutputPath as i, writeCatalogueMessages as n, reconcileLocaleMessages as o, declarationPathFor as r, readCatalogueMessages as t };
67
+ export { mergeExtractedMessages as a, expandBucketOutputPath as i, writeCatalogueMessages as n, pruneLocaleMessages as o, declarationPathFor as r, readCatalogueMessages as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saykit/config",
3
- "version": "0.0.0-beta-20260720032009",
3
+ "version": "0.0.0-beta-20260720035025",
4
4
  "description": "CLI and configuration tooling for saykit",
5
5
  "keywords": [
6
6
  "cli",