@twin.org/merge-locales 0.9.2 → 0.9.3-next.10

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/es/cli.js CHANGED
@@ -20,7 +20,7 @@ export class CLI extends CLIBase {
20
20
  return this.execute({
21
21
  title: "TWIN Merge Locales",
22
22
  appName: "merge-locales",
23
- version: "0.9.2", // x-release-please-version
23
+ version: "0.9.3-next.10", // x-release-please-version
24
24
  icon: "⚙️ ",
25
25
  supportsEnvFiles: false,
26
26
  overrideOutputWidth: options?.overrideOutputWidth
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;GAEG;AACH,MAAM,OAAO,GAAI,SAAQ,OAAO;IAC/B;;;;;;;OAOG;IACI,KAAK,CAAC,GAAG,CACf,IAAc,EACd,gBAAyB,EACzB,OAA0C;QAE1C,OAAO,IAAI,CAAC,OAAO,CAClB;YACC,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,OAAO,EAAE,2BAA2B;YAC7C,IAAI,EAAE,KAAK;YACX,gBAAgB,EAAE,KAAK;YACvB,mBAAmB,EAAE,OAAO,EAAE,mBAAmB;SACjD,EACD,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,EACzF,IAAI,CACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACO,aAAa,CAAC,OAAgB;QACvC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { CLIBase } from \"@twin.org/cli-core\";\nimport type { Command } from \"commander\";\nimport { buildCommandMergeLocales } from \"./commands/mergeLocales.js\";\n\n/**\n * The main entry point for the CLI.\n */\nexport class CLI extends CLIBase {\n\t/**\n\t * Run the app.\n\t * @param argv The process arguments.\n\t * @param localesDirectory The directory for the locales, default to relative to the script.\n\t * @param options Additional options.\n\t * @param options.overrideOutputWidth Override the output width.\n\t * @returns The exit code.\n\t */\n\tpublic async run(\n\t\targv: string[],\n\t\tlocalesDirectory?: string,\n\t\toptions?: { overrideOutputWidth?: number }\n\t): Promise<number> {\n\t\treturn this.execute(\n\t\t\t{\n\t\t\t\ttitle: \"TWIN Merge Locales\",\n\t\t\t\tappName: \"merge-locales\",\n\t\t\t\tversion: \"0.9.2\", // x-release-please-version\n\t\t\t\ticon: \"⚙️ \",\n\t\t\t\tsupportsEnvFiles: false,\n\t\t\t\toverrideOutputWidth: options?.overrideOutputWidth\n\t\t\t},\n\t\t\tlocalesDirectory ?? path.join(path.dirname(fileURLToPath(import.meta.url)), \"../locales\"),\n\t\t\targv\n\t\t);\n\t}\n\n\t/**\n\t * Configure any options or actions at the root program level.\n\t * @param program The root program command.\n\t */\n\tprotected configureRoot(program: Command): void {\n\t\tbuildCommandMergeLocales(program);\n\t}\n}\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,uCAAuC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;GAEG;AACH,MAAM,OAAO,GAAI,SAAQ,OAAO;IAC/B;;;;;;;OAOG;IACI,KAAK,CAAC,GAAG,CACf,IAAc,EACd,gBAAyB,EACzB,OAA0C;QAE1C,OAAO,IAAI,CAAC,OAAO,CAClB;YACC,KAAK,EAAE,oBAAoB;YAC3B,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,eAAe,EAAE,2BAA2B;YACrD,IAAI,EAAE,KAAK;YACX,gBAAgB,EAAE,KAAK;YACvB,mBAAmB,EAAE,OAAO,EAAE,mBAAmB;SACjD,EACD,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,EACzF,IAAI,CACJ,CAAC;IACH,CAAC;IAED;;;OAGG;IACO,aAAa,CAAC,OAAgB;QACvC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { CLIBase } from \"@twin.org/cli-core\";\nimport type { Command } from \"commander\";\nimport { buildCommandMergeLocales } from \"./commands/mergeLocales.js\";\n\n/**\n * The main entry point for the CLI.\n */\nexport class CLI extends CLIBase {\n\t/**\n\t * Run the app.\n\t * @param argv The process arguments.\n\t * @param localesDirectory The directory for the locales, default to relative to the script.\n\t * @param options Additional options.\n\t * @param options.overrideOutputWidth Override the output width.\n\t * @returns The exit code.\n\t */\n\tpublic async run(\n\t\targv: string[],\n\t\tlocalesDirectory?: string,\n\t\toptions?: { overrideOutputWidth?: number }\n\t): Promise<number> {\n\t\treturn this.execute(\n\t\t\t{\n\t\t\t\ttitle: \"TWIN Merge Locales\",\n\t\t\t\tappName: \"merge-locales\",\n\t\t\t\tversion: \"0.9.3-next.10\", // x-release-please-version\n\t\t\t\ticon: \"⚙️ \",\n\t\t\t\tsupportsEnvFiles: false,\n\t\t\t\toverrideOutputWidth: options?.overrideOutputWidth\n\t\t\t},\n\t\t\tlocalesDirectory ?? path.join(path.dirname(fileURLToPath(import.meta.url)), \"../locales\"),\n\t\t\targv\n\t\t);\n\t}\n\n\t/**\n\t * Configure any options or actions at the root program level.\n\t * @param program The root program command.\n\t */\n\tprotected configureRoot(program: Command): void {\n\t\tbuildCommandMergeLocales(program);\n\t}\n}\n"]}
@@ -57,8 +57,6 @@ export async function mergeLocales(workingDirectory, config) {
57
57
  locales.push({ label: "English", code: "en" });
58
58
  }
59
59
  CLIDisplay.value(I18n.formatMessage("commands.merge-locales.labels.outputDirectory"), outputDirectory);
60
- const npmRoot = await CLIUtils.findNpmRoot(workingDirectory);
61
- CLIDisplay.value(I18n.formatMessage("commands.merge-locales.labels.npmRoot"), npmRoot);
62
60
  CLIDisplay.break();
63
61
  CLIDisplay.task(I18n.formatMessage("commands.merge-locales.progress.creatingOutputDirectory"), outputDirectory);
64
62
  try {
@@ -66,22 +64,34 @@ export async function mergeLocales(workingDirectory, config) {
66
64
  }
67
65
  catch { }
68
66
  await mkdir(outputDirectory, { recursive: true });
69
- let packageNames = [];
70
- const packageJson = await findDependencies(npmRoot, path.join(workingDirectory, "package.json"), packageNames);
67
+ const packageLocations = {};
68
+ const packageJson = await findDependencies(workingDirectory, path.join(workingDirectory, "package.json"), packageLocations);
71
69
  excludePackages.push("@twin.org/merge-locales");
72
70
  excludePackages.push("@twin.org/nameof");
73
71
  excludePackages.push("@twin.org/nameof-transformer");
74
- packageNames = packageNames.filter(pkg => !excludePackages.includes(pkg));
75
- packageNames.push(...includePackages);
72
+ const packageNames = Object.keys(packageLocations).filter(pkg => !excludePackages.includes(pkg));
73
+ for (const includePackage of includePackages) {
74
+ if (!packageNames.includes(includePackage)) {
75
+ const packageRoot = packageLocations[includePackage] ??
76
+ (await CLIUtils.findPackageRoot(includePackage, workingDirectory));
77
+ if (Is.stringValue(packageRoot)) {
78
+ packageLocations[includePackage] = packageRoot;
79
+ packageNames.push(includePackage);
80
+ }
81
+ else {
82
+ CLIDisplay.warning(`${I18n.formatMessage("commands.merge-locales.labels.packageNotFound")}: ${includePackage}`);
83
+ }
84
+ }
85
+ }
76
86
  CLIDisplay.break();
77
87
  CLIDisplay.section(I18n.formatMessage("commands.merge-locales.labels.sourcePackages"));
78
88
  for (const packageName of packageNames) {
79
- CLIDisplay.value("", packageName, 1);
89
+ CLIDisplay.value(packageName, packageLocations[packageName], 1);
80
90
  }
81
91
  CLIDisplay.break();
82
92
  const localeDictionaries = {};
83
93
  for (const packageName of packageNames) {
84
- const packageLocalDirectory = path.join(npmRoot, packageName, "locales");
94
+ const packageLocalDirectory = path.join(packageLocations[packageName], "locales");
85
95
  await mergePackageLocales(packageLocalDirectory, packageName, locales, localeDictionaries);
86
96
  }
87
97
  // Merge the main package last so that it can override any other packages.
@@ -121,32 +131,46 @@ async function mergePackageLocales(packageLocalDirectory, packageName, locales,
121
131
  }
122
132
  /**
123
133
  * Find dependencies for the package.
124
- * @param npmRoot The root of the NPM packages.
134
+ * @param searchFolder The folder to resolve the dependencies from.
125
135
  * @param packageJsonPath The path to the package.json.
126
- * @param packageNames The package names to add to.
136
+ * @param packageLocations The package locations to add to, keyed by package name.
127
137
  * @returns The package details.
128
138
  * @internal
129
139
  */
130
- async function findDependencies(npmRoot, packageJsonPath, packageNames) {
140
+ async function findDependencies(searchFolder, packageJsonPath, packageLocations) {
131
141
  const packageJson = await CLIUtils.readJsonFile(packageJsonPath);
132
142
  if (Is.objectValue(packageJson?.dependencies)) {
133
143
  for (const pkg in packageJson.dependencies) {
134
- if (pkg.startsWith("@twin.org") && !packageNames.includes(pkg)) {
135
- packageNames.push(pkg);
136
- const packagePath = path.join(npmRoot, pkg, "package.json");
137
- await findDependencies(npmRoot, packagePath, packageNames);
138
- }
144
+ await findPackageDependencies(searchFolder, pkg, packageLocations);
139
145
  }
140
146
  }
141
147
  if (Is.objectValue(packageJson?.peerDependencies)) {
142
148
  for (const pkg in packageJson.peerDependencies) {
143
- if (pkg.startsWith("@twin.org") && !packageNames.includes(pkg)) {
144
- packageNames.push(pkg);
145
- const packagePath = path.join(npmRoot, pkg, "package.json");
146
- await findDependencies(npmRoot, packagePath, packageNames);
147
- }
149
+ await findPackageDependencies(searchFolder, pkg, packageLocations);
148
150
  }
149
151
  }
150
152
  return packageJson ?? {};
151
153
  }
154
+ /**
155
+ * Locate a package and find its dependencies.
156
+ * @param searchFolder The folder to resolve the package from.
157
+ * @param packageName The name of the package to locate.
158
+ * @param packageLocations The package locations to add to, keyed by package name.
159
+ * @internal
160
+ */
161
+ async function findPackageDependencies(searchFolder, packageName, packageLocations) {
162
+ if (!packageName.startsWith("@twin.org") || Is.stringValue(packageLocations[packageName])) {
163
+ return;
164
+ }
165
+ // The location of a package can not be assumed to be in a single root node_modules folder,
166
+ // as package managers such nest the dependencies of each package, so walk the tree
167
+ // from the folder of the package which depends on it.
168
+ const packageRoot = await CLIUtils.findPackageRoot(packageName, searchFolder);
169
+ if (!Is.stringValue(packageRoot)) {
170
+ CLIDisplay.warning(`${I18n.formatMessage("commands.merge-locales.labels.packageNotFound")}: ${packageName}`);
171
+ return;
172
+ }
173
+ packageLocations[packageName] = packageRoot;
174
+ await findDependencies(packageRoot, path.join(packageRoot, "package.json"), packageLocations);
175
+ }
152
176
  //# sourceMappingURL=mergeLocales.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mergeLocales.js","sourceRoot":"","sources":["../../../src/commands/mergeLocales.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport {\n\tGeneralError,\n\tI18n,\n\tIs,\n\tObjectHelper,\n\ttype ILocale,\n\ttype ILocaleDictionary\n} from \"@twin.org/core\";\nimport type { Command } from \"commander\";\nimport type { IMergeLocalesConfig } from \"../models/IMergeLocalesConfig.js\";\nimport type { IPackageJson } from \"../models/IPackageJson.js\";\n\n/**\n * Build the root command to be consumed by the CLI.\n * @param program The command to build on.\n */\nexport function buildCommandMergeLocales(program: Command): void {\n\tprogram\n\t\t.option(\n\t\t\tI18n.formatMessage(\"commands.merge-locales.options.config.param\"),\n\t\t\tI18n.formatMessage(\"commands.merge-locales.options.config.description\")\n\t\t)\n\t\t.action(async opts => {\n\t\t\tawait actionCommandMergeLocales(opts);\n\t\t});\n}\n\n/**\n * Action the root command.\n * @param opts The options for the command.\n * @param opts.config The optional configuration file.\n */\nexport async function actionCommandMergeLocales(opts: { config?: string }): Promise<void> {\n\tlet config: IMergeLocalesConfig | undefined;\n\tif (Is.stringValue(opts.config)) {\n\t\ttry {\n\t\t\tconst configJson = path.resolve(opts.config);\n\t\t\tCLIDisplay.value(I18n.formatMessage(\"commands.merge-locales.labels.configJson\"), configJson);\n\t\t\tCLIDisplay.break();\n\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"commands.merge-locales.progress.loadingConfigJson\"));\n\t\t\tCLIDisplay.break();\n\n\t\t\tconfig = await CLIUtils.readJsonFile<IMergeLocalesConfig>(configJson);\n\t\t\tCLIDisplay.break();\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\"commands\", \"commands.merge-locales.configFailed\", undefined, err);\n\t\t}\n\n\t\tif (Is.empty(config)) {\n\t\t\tthrow new GeneralError(\"commands\", \"commands.merge-locales.configFailed\");\n\t\t}\n\t}\n\n\tawait mergeLocales(process.cwd(), config ?? {});\n\n\tCLIDisplay.done();\n}\n\n/**\n * Merge the locales.\n * @param workingDirectory The folder the app was run from.\n * @param config The configuration for the app.\n */\nexport async function mergeLocales(\n\tworkingDirectory: string,\n\tconfig: IMergeLocalesConfig\n): Promise<void> {\n\tCLIDisplay.value(\n\t\tI18n.formatMessage(\"commands.merge-locales.labels.workingDirectory\"),\n\t\tworkingDirectory\n\t);\n\n\tconst outputDirectory = path.resolve(config.outputDirectory ?? \"./dist/locales\");\n\tconst locales = config.locales ?? [];\n\tconst includePackages = config.includePackages ?? [];\n\tconst excludePackages = config.excludePackages ?? [];\n\n\tif (locales.length === 0) {\n\t\tlocales.push({ label: \"English\", code: \"en\" });\n\t}\n\tCLIDisplay.value(\n\t\tI18n.formatMessage(\"commands.merge-locales.labels.outputDirectory\"),\n\t\toutputDirectory\n\t);\n\n\tconst npmRoot = await CLIUtils.findNpmRoot(workingDirectory);\n\tCLIDisplay.value(I18n.formatMessage(\"commands.merge-locales.labels.npmRoot\"), npmRoot);\n\tCLIDisplay.break();\n\n\tCLIDisplay.task(\n\t\tI18n.formatMessage(\"commands.merge-locales.progress.creatingOutputDirectory\"),\n\t\toutputDirectory\n\t);\n\n\ttry {\n\t\tawait rm(outputDirectory, { recursive: true });\n\t} catch {}\n\tawait mkdir(outputDirectory, { recursive: true });\n\n\tlet packageNames: string[] = [];\n\n\tconst packageJson = await findDependencies(\n\t\tnpmRoot,\n\t\tpath.join(workingDirectory, \"package.json\"),\n\t\tpackageNames\n\t);\n\n\texcludePackages.push(\"@twin.org/merge-locales\");\n\texcludePackages.push(\"@twin.org/nameof\");\n\texcludePackages.push(\"@twin.org/nameof-transformer\");\n\n\tpackageNames = packageNames.filter(pkg => !excludePackages.includes(pkg));\n\tpackageNames.push(...includePackages);\n\n\tCLIDisplay.break();\n\tCLIDisplay.section(I18n.formatMessage(\"commands.merge-locales.labels.sourcePackages\"));\n\tfor (const packageName of packageNames) {\n\t\tCLIDisplay.value(\"\", packageName, 1);\n\t}\n\tCLIDisplay.break();\n\n\tconst localeDictionaries: { [locale: string]: ILocaleDictionary } = {};\n\n\tfor (const packageName of packageNames) {\n\t\tconst packageLocalDirectory = path.join(npmRoot, packageName, \"locales\");\n\t\tawait mergePackageLocales(packageLocalDirectory, packageName, locales, localeDictionaries);\n\t}\n\n\t// Merge the main package last so that it can override any other packages.\n\tif (Is.stringValue(packageJson.name)) {\n\t\tawait mergePackageLocales(\n\t\t\tpath.join(workingDirectory, \"locales\"),\n\t\t\tpackageJson.name,\n\t\t\tlocales,\n\t\t\tlocaleDictionaries\n\t\t);\n\t}\n\n\tCLIDisplay.break();\n\tCLIDisplay.task(I18n.formatMessage(\"commands.merge-locales.progress.writingMergedLocales\"));\n\n\tfor (const localeDictionary in localeDictionaries) {\n\t\tconst localeFile = path.join(outputDirectory, `${localeDictionary}.json`);\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"commands.merge-locales.labels.writingLocale\"),\n\t\t\tlocaleFile,\n\t\t\t1\n\t\t);\n\t\tawait writeFile(\n\t\t\tlocaleFile,\n\t\t\t`${JSON.stringify(localeDictionaries[localeDictionary], undefined, \"\\t\")}\\n`,\n\t\t\t\"utf8\"\n\t\t);\n\t}\n\tCLIDisplay.break();\n}\n\n/**\n * Merge the locales for a package.\n * @param packageLocalDirectory The root of the NPM packages.\n * @param packageName The name of the package.\n * @param locales The locales to merge.\n * @internal\n */\nasync function mergePackageLocales(\n\tpackageLocalDirectory: string,\n\tpackageName: string,\n\tlocales: ILocale[],\n\tlocaleDictionaries: { [locale: string]: ILocaleDictionary }\n): Promise<void> {\n\tCLIDisplay.task(\n\t\tI18n.formatMessage(\"commands.merge-locales.progress.mergingLocalesForPackage\"),\n\t\tpackageName\n\t);\n\n\tif (await CLIUtils.dirExists(packageLocalDirectory)) {\n\t\tfor (const locale of locales) {\n\t\t\tconst localeFile = path.join(packageLocalDirectory, `${locale.code}.json`);\n\t\t\tif (await CLIUtils.dirExists(localeFile)) {\n\t\t\t\tCLIDisplay.value(\n\t\t\t\t\tI18n.formatMessage(\"commands.merge-locales.labels.mergingLocale\"),\n\t\t\t\t\tlocale.code,\n\t\t\t\t\t1\n\t\t\t\t);\n\n\t\t\t\tconst localeDictionary = await CLIUtils.readJsonFile<ILocaleDictionary>(localeFile);\n\t\t\t\tlocaleDictionaries[locale.code] ??= {};\n\t\t\t\tlocaleDictionaries[locale.code] = ObjectHelper.merge(\n\t\t\t\t\tlocaleDictionaries[locale.code],\n\t\t\t\t\tlocaleDictionary\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\tCLIDisplay.break();\n}\n\n/**\n * Find dependencies for the package.\n * @param npmRoot The root of the NPM packages.\n * @param packageJsonPath The path to the package.json.\n * @param packageNames The package names to add to.\n * @returns The package details.\n * @internal\n */\nasync function findDependencies(\n\tnpmRoot: string,\n\tpackageJsonPath: string,\n\tpackageNames: string[]\n): Promise<IPackageJson> {\n\tconst packageJson = await CLIUtils.readJsonFile<IPackageJson>(packageJsonPath);\n\n\tif (Is.objectValue(packageJson?.dependencies)) {\n\t\tfor (const pkg in packageJson.dependencies) {\n\t\t\tif (pkg.startsWith(\"@twin.org\") && !packageNames.includes(pkg)) {\n\t\t\t\tpackageNames.push(pkg);\n\t\t\t\tconst packagePath = path.join(npmRoot, pkg, \"package.json\");\n\t\t\t\tawait findDependencies(npmRoot, packagePath, packageNames);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (Is.objectValue(packageJson?.peerDependencies)) {\n\t\tfor (const pkg in packageJson.peerDependencies) {\n\t\t\tif (pkg.startsWith(\"@twin.org\") && !packageNames.includes(pkg)) {\n\t\t\t\tpackageNames.push(pkg);\n\t\t\t\tconst packagePath = path.join(npmRoot, pkg, \"package.json\");\n\t\t\t\tawait findDependencies(npmRoot, packagePath, packageNames);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn packageJson ?? {};\n}\n"]}
1
+ {"version":3,"file":"mergeLocales.js","sourceRoot":"","sources":["../../../src/commands/mergeLocales.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { CLIDisplay, CLIUtils } from \"@twin.org/cli-core\";\nimport {\n\tGeneralError,\n\tI18n,\n\tIs,\n\tObjectHelper,\n\ttype ILocale,\n\ttype ILocaleDictionary\n} from \"@twin.org/core\";\nimport type { Command } from \"commander\";\nimport type { IMergeLocalesConfig } from \"../models/IMergeLocalesConfig.js\";\nimport type { IPackageJson } from \"../models/IPackageJson.js\";\n\n/**\n * Build the root command to be consumed by the CLI.\n * @param program The command to build on.\n */\nexport function buildCommandMergeLocales(program: Command): void {\n\tprogram\n\t\t.option(\n\t\t\tI18n.formatMessage(\"commands.merge-locales.options.config.param\"),\n\t\t\tI18n.formatMessage(\"commands.merge-locales.options.config.description\")\n\t\t)\n\t\t.action(async opts => {\n\t\t\tawait actionCommandMergeLocales(opts);\n\t\t});\n}\n\n/**\n * Action the root command.\n * @param opts The options for the command.\n * @param opts.config The optional configuration file.\n */\nexport async function actionCommandMergeLocales(opts: { config?: string }): Promise<void> {\n\tlet config: IMergeLocalesConfig | undefined;\n\tif (Is.stringValue(opts.config)) {\n\t\ttry {\n\t\t\tconst configJson = path.resolve(opts.config);\n\t\t\tCLIDisplay.value(I18n.formatMessage(\"commands.merge-locales.labels.configJson\"), configJson);\n\t\t\tCLIDisplay.break();\n\n\t\t\tCLIDisplay.task(I18n.formatMessage(\"commands.merge-locales.progress.loadingConfigJson\"));\n\t\t\tCLIDisplay.break();\n\n\t\t\tconfig = await CLIUtils.readJsonFile<IMergeLocalesConfig>(configJson);\n\t\t\tCLIDisplay.break();\n\t\t} catch (err) {\n\t\t\tthrow new GeneralError(\"commands\", \"commands.merge-locales.configFailed\", undefined, err);\n\t\t}\n\n\t\tif (Is.empty(config)) {\n\t\t\tthrow new GeneralError(\"commands\", \"commands.merge-locales.configFailed\");\n\t\t}\n\t}\n\n\tawait mergeLocales(process.cwd(), config ?? {});\n\n\tCLIDisplay.done();\n}\n\n/**\n * Merge the locales.\n * @param workingDirectory The folder the app was run from.\n * @param config The configuration for the app.\n */\nexport async function mergeLocales(\n\tworkingDirectory: string,\n\tconfig: IMergeLocalesConfig\n): Promise<void> {\n\tCLIDisplay.value(\n\t\tI18n.formatMessage(\"commands.merge-locales.labels.workingDirectory\"),\n\t\tworkingDirectory\n\t);\n\n\tconst outputDirectory = path.resolve(config.outputDirectory ?? \"./dist/locales\");\n\tconst locales = config.locales ?? [];\n\tconst includePackages = config.includePackages ?? [];\n\tconst excludePackages = config.excludePackages ?? [];\n\n\tif (locales.length === 0) {\n\t\tlocales.push({ label: \"English\", code: \"en\" });\n\t}\n\tCLIDisplay.value(\n\t\tI18n.formatMessage(\"commands.merge-locales.labels.outputDirectory\"),\n\t\toutputDirectory\n\t);\n\n\tCLIDisplay.break();\n\n\tCLIDisplay.task(\n\t\tI18n.formatMessage(\"commands.merge-locales.progress.creatingOutputDirectory\"),\n\t\toutputDirectory\n\t);\n\n\ttry {\n\t\tawait rm(outputDirectory, { recursive: true });\n\t} catch {}\n\tawait mkdir(outputDirectory, { recursive: true });\n\n\tconst packageLocations: { [packageName: string]: string } = {};\n\n\tconst packageJson = await findDependencies(\n\t\tworkingDirectory,\n\t\tpath.join(workingDirectory, \"package.json\"),\n\t\tpackageLocations\n\t);\n\n\texcludePackages.push(\"@twin.org/merge-locales\");\n\texcludePackages.push(\"@twin.org/nameof\");\n\texcludePackages.push(\"@twin.org/nameof-transformer\");\n\n\tconst packageNames = Object.keys(packageLocations).filter(pkg => !excludePackages.includes(pkg));\n\n\tfor (const includePackage of includePackages) {\n\t\tif (!packageNames.includes(includePackage)) {\n\t\t\tconst packageRoot =\n\t\t\t\tpackageLocations[includePackage] ??\n\t\t\t\t(await CLIUtils.findPackageRoot(includePackage, workingDirectory));\n\n\t\t\tif (Is.stringValue(packageRoot)) {\n\t\t\t\tpackageLocations[includePackage] = packageRoot;\n\t\t\t\tpackageNames.push(includePackage);\n\t\t\t} else {\n\t\t\t\tCLIDisplay.warning(\n\t\t\t\t\t`${I18n.formatMessage(\"commands.merge-locales.labels.packageNotFound\")}: ${includePackage}`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tCLIDisplay.break();\n\tCLIDisplay.section(I18n.formatMessage(\"commands.merge-locales.labels.sourcePackages\"));\n\tfor (const packageName of packageNames) {\n\t\tCLIDisplay.value(packageName, packageLocations[packageName], 1);\n\t}\n\tCLIDisplay.break();\n\n\tconst localeDictionaries: { [locale: string]: ILocaleDictionary } = {};\n\n\tfor (const packageName of packageNames) {\n\t\tconst packageLocalDirectory = path.join(packageLocations[packageName], \"locales\");\n\t\tawait mergePackageLocales(packageLocalDirectory, packageName, locales, localeDictionaries);\n\t}\n\n\t// Merge the main package last so that it can override any other packages.\n\tif (Is.stringValue(packageJson.name)) {\n\t\tawait mergePackageLocales(\n\t\t\tpath.join(workingDirectory, \"locales\"),\n\t\t\tpackageJson.name,\n\t\t\tlocales,\n\t\t\tlocaleDictionaries\n\t\t);\n\t}\n\n\tCLIDisplay.break();\n\tCLIDisplay.task(I18n.formatMessage(\"commands.merge-locales.progress.writingMergedLocales\"));\n\n\tfor (const localeDictionary in localeDictionaries) {\n\t\tconst localeFile = path.join(outputDirectory, `${localeDictionary}.json`);\n\t\tCLIDisplay.value(\n\t\t\tI18n.formatMessage(\"commands.merge-locales.labels.writingLocale\"),\n\t\t\tlocaleFile,\n\t\t\t1\n\t\t);\n\t\tawait writeFile(\n\t\t\tlocaleFile,\n\t\t\t`${JSON.stringify(localeDictionaries[localeDictionary], undefined, \"\\t\")}\\n`,\n\t\t\t\"utf8\"\n\t\t);\n\t}\n\tCLIDisplay.break();\n}\n\n/**\n * Merge the locales for a package.\n * @param packageLocalDirectory The root of the NPM packages.\n * @param packageName The name of the package.\n * @param locales The locales to merge.\n * @internal\n */\nasync function mergePackageLocales(\n\tpackageLocalDirectory: string,\n\tpackageName: string,\n\tlocales: ILocale[],\n\tlocaleDictionaries: { [locale: string]: ILocaleDictionary }\n): Promise<void> {\n\tCLIDisplay.task(\n\t\tI18n.formatMessage(\"commands.merge-locales.progress.mergingLocalesForPackage\"),\n\t\tpackageName\n\t);\n\n\tif (await CLIUtils.dirExists(packageLocalDirectory)) {\n\t\tfor (const locale of locales) {\n\t\t\tconst localeFile = path.join(packageLocalDirectory, `${locale.code}.json`);\n\t\t\tif (await CLIUtils.dirExists(localeFile)) {\n\t\t\t\tCLIDisplay.value(\n\t\t\t\t\tI18n.formatMessage(\"commands.merge-locales.labels.mergingLocale\"),\n\t\t\t\t\tlocale.code,\n\t\t\t\t\t1\n\t\t\t\t);\n\n\t\t\t\tconst localeDictionary = await CLIUtils.readJsonFile<ILocaleDictionary>(localeFile);\n\t\t\t\tlocaleDictionaries[locale.code] ??= {};\n\t\t\t\tlocaleDictionaries[locale.code] = ObjectHelper.merge(\n\t\t\t\t\tlocaleDictionaries[locale.code],\n\t\t\t\t\tlocaleDictionary\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\tCLIDisplay.break();\n}\n\n/**\n * Find dependencies for the package.\n * @param searchFolder The folder to resolve the dependencies from.\n * @param packageJsonPath The path to the package.json.\n * @param packageLocations The package locations to add to, keyed by package name.\n * @returns The package details.\n * @internal\n */\nasync function findDependencies(\n\tsearchFolder: string,\n\tpackageJsonPath: string,\n\tpackageLocations: { [packageName: string]: string }\n): Promise<IPackageJson> {\n\tconst packageJson = await CLIUtils.readJsonFile<IPackageJson>(packageJsonPath);\n\n\tif (Is.objectValue(packageJson?.dependencies)) {\n\t\tfor (const pkg in packageJson.dependencies) {\n\t\t\tawait findPackageDependencies(searchFolder, pkg, packageLocations);\n\t\t}\n\t}\n\n\tif (Is.objectValue(packageJson?.peerDependencies)) {\n\t\tfor (const pkg in packageJson.peerDependencies) {\n\t\t\tawait findPackageDependencies(searchFolder, pkg, packageLocations);\n\t\t}\n\t}\n\n\treturn packageJson ?? {};\n}\n\n/**\n * Locate a package and find its dependencies.\n * @param searchFolder The folder to resolve the package from.\n * @param packageName The name of the package to locate.\n * @param packageLocations The package locations to add to, keyed by package name.\n * @internal\n */\nasync function findPackageDependencies(\n\tsearchFolder: string,\n\tpackageName: string,\n\tpackageLocations: { [packageName: string]: string }\n): Promise<void> {\n\tif (!packageName.startsWith(\"@twin.org\") || Is.stringValue(packageLocations[packageName])) {\n\t\treturn;\n\t}\n\n\t// The location of a package can not be assumed to be in a single root node_modules folder,\n\t// as package managers such nest the dependencies of each package, so walk the tree\n\t// from the folder of the package which depends on it.\n\tconst packageRoot = await CLIUtils.findPackageRoot(packageName, searchFolder);\n\n\tif (!Is.stringValue(packageRoot)) {\n\t\tCLIDisplay.warning(\n\t\t\t`${I18n.formatMessage(\"commands.merge-locales.labels.packageNotFound\")}: ${packageName}`\n\t\t);\n\t\treturn;\n\t}\n\n\tpackageLocations[packageName] = packageRoot;\n\n\tawait findDependencies(packageRoot, path.join(packageRoot, \"package.json\"), packageLocations);\n}\n"]}
@@ -104,7 +104,10 @@
104
104
  "factory": {
105
105
  "noUnregister": "There is no {typeName} registered with the name \"{name}\"",
106
106
  "noGet": "The requested {typeName} \"{name}\" does not exist in the factory",
107
- "noCreate": "The requested {typeName} \"{name}\" cannot be created by the factory, with params \"{params}\""
107
+ "noCreate": "The requested {typeName} \"{name}\" cannot be created by the factory, with params \"{params}\"",
108
+ "noFacade": "The requested facade \"{name}\" is not registered, so it cannot be applied to the {typeName} factory",
109
+ "noFacadeOnFacades": "Facades cannot be applied to the facade factory itself",
110
+ "noFacadeWrap": "The facade \"{name}\" did not return a wrapped instance for the {typeName} factory"
108
111
  },
109
112
  "bitString": {
110
113
  "outOfRange": "The index should be >= 0 and less than the length of the bit string, the index is \"{index}\" and the number of bit is \"{numberBits}\""
@@ -124,7 +127,7 @@
124
127
  "mutex": {
125
128
  "lockNotFound": "The key \"{key}\" has no active lock",
126
129
  "lockAlreadyReleased": "The key \"{key}\" is not currently locked",
127
- "lockTimeout": "Failed to acquire lock for key \"{key}\" within the timeout of {timeout} milliseconds",
130
+ "lockTimeout": "Failed to acquire lock for key \"{key}\" within the timeout of {timeoutMs} milliseconds",
128
131
  "bufferFetchFailed": "Failed to retrieve shared buffer for key \"{key}\" from the main thread",
129
132
  "invalidTimeout": "The timeout value \"{timeoutMs}\" is invalid, it must be a non-negative integer"
130
133
  },
@@ -215,7 +218,7 @@
215
218
  "configJson": "Config JSON",
216
219
  "workingDirectory": "Working Directory",
217
220
  "outputDirectory": "Output Directory",
218
- "npmRoot": "NPM Root",
221
+ "packageNotFound": "Package Not Found",
219
222
  "sourcePackages": "Source Packages",
220
223
  "writingLocale": "Writing Locale",
221
224
  "mergingLocale": "Merging Locale"
package/docs/changelog.md CHANGED
@@ -1,5 +1,204 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.3-next.10](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.9...merge-locales-v0.9.3-next.10) (2026-09-10)
4
+
5
+
6
+ ### Miscellaneous Chores
7
+
8
+ * **merge-locales:** Synchronize repo versions
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @twin.org/cli-core bumped from 0.9.3-next.9 to 0.9.3-next.10
16
+ * @twin.org/core bumped from 0.9.3-next.9 to 0.9.3-next.10
17
+ * @twin.org/nameof bumped from 0.9.3-next.9 to 0.9.3-next.10
18
+ * devDependencies
19
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.9 to 0.9.3-next.10
20
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.9 to 0.9.3-next.10
21
+
22
+ ## [0.9.3-next.9](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.8...merge-locales-v0.9.3-next.9) (2026-09-10)
23
+
24
+
25
+ ### Miscellaneous Chores
26
+
27
+ * **merge-locales:** Synchronize repo versions
28
+
29
+
30
+ ### Dependencies
31
+
32
+ * The following workspace dependencies were updated
33
+ * dependencies
34
+ * @twin.org/cli-core bumped from 0.9.3-next.8 to 0.9.3-next.9
35
+ * @twin.org/core bumped from 0.9.3-next.8 to 0.9.3-next.9
36
+ * @twin.org/nameof bumped from 0.9.3-next.8 to 0.9.3-next.9
37
+ * devDependencies
38
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.8 to 0.9.3-next.9
39
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.8 to 0.9.3-next.9
40
+
41
+ ## [0.9.3-next.8](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.7...merge-locales-v0.9.3-next.8) (2026-09-07)
42
+
43
+
44
+ ### Features
45
+
46
+ * improve node_modules location detection ([#486](https://github.com/iotaledger/twin-framework/issues/486)) ([c786853](https://github.com/iotaledger/twin-framework/commit/c7868538e9074f789577c0ab55552f3bcec0ef0e))
47
+
48
+
49
+ ### Dependencies
50
+
51
+ * The following workspace dependencies were updated
52
+ * dependencies
53
+ * @twin.org/cli-core bumped from 0.9.3-next.7 to 0.9.3-next.8
54
+ * @twin.org/core bumped from 0.9.3-next.7 to 0.9.3-next.8
55
+ * @twin.org/nameof bumped from 0.9.3-next.7 to 0.9.3-next.8
56
+ * devDependencies
57
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.7 to 0.9.3-next.8
58
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.7 to 0.9.3-next.8
59
+
60
+ ## [0.9.3-next.7](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.6...merge-locales-v0.9.3-next.7) (2026-09-07)
61
+
62
+
63
+ ### Miscellaneous Chores
64
+
65
+ * **merge-locales:** Synchronize repo versions
66
+
67
+
68
+ ### Dependencies
69
+
70
+ * The following workspace dependencies were updated
71
+ * dependencies
72
+ * @twin.org/cli-core bumped from 0.9.3-next.6 to 0.9.3-next.7
73
+ * @twin.org/core bumped from 0.9.3-next.6 to 0.9.3-next.7
74
+ * @twin.org/nameof bumped from 0.9.3-next.6 to 0.9.3-next.7
75
+ * devDependencies
76
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.6 to 0.9.3-next.7
77
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.6 to 0.9.3-next.7
78
+
79
+ ## [0.9.3-next.6](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.5...merge-locales-v0.9.3-next.6) (2026-09-07)
80
+
81
+
82
+ ### Miscellaneous Chores
83
+
84
+ * **merge-locales:** Synchronize repo versions
85
+
86
+
87
+ ### Dependencies
88
+
89
+ * The following workspace dependencies were updated
90
+ * dependencies
91
+ * @twin.org/cli-core bumped from 0.9.3-next.5 to 0.9.3-next.6
92
+ * @twin.org/core bumped from 0.9.3-next.5 to 0.9.3-next.6
93
+ * @twin.org/nameof bumped from 0.9.3-next.5 to 0.9.3-next.6
94
+ * devDependencies
95
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.5 to 0.9.3-next.6
96
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.5 to 0.9.3-next.6
97
+
98
+ ## [0.9.3-next.5](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.4...merge-locales-v0.9.3-next.5) (2026-09-04)
99
+
100
+
101
+ ### Miscellaneous Chores
102
+
103
+ * **merge-locales:** Synchronize repo versions
104
+
105
+
106
+ ### Dependencies
107
+
108
+ * The following workspace dependencies were updated
109
+ * dependencies
110
+ * @twin.org/cli-core bumped from 0.9.3-next.4 to 0.9.3-next.5
111
+ * @twin.org/core bumped from 0.9.3-next.4 to 0.9.3-next.5
112
+ * @twin.org/nameof bumped from 0.9.3-next.4 to 0.9.3-next.5
113
+ * devDependencies
114
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.4 to 0.9.3-next.5
115
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.4 to 0.9.3-next.5
116
+
117
+ ## [0.9.3-next.4](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.3...merge-locales-v0.9.3-next.4) (2026-09-04)
118
+
119
+
120
+ ### Miscellaneous Chores
121
+
122
+ * **merge-locales:** Synchronize repo versions
123
+
124
+
125
+ ### Dependencies
126
+
127
+ * The following workspace dependencies were updated
128
+ * dependencies
129
+ * @twin.org/cli-core bumped from 0.9.3-next.3 to 0.9.3-next.4
130
+ * @twin.org/core bumped from 0.9.3-next.3 to 0.9.3-next.4
131
+ * @twin.org/nameof bumped from 0.9.3-next.3 to 0.9.3-next.4
132
+ * devDependencies
133
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.3 to 0.9.3-next.4
134
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.3 to 0.9.3-next.4
135
+
136
+ ## [0.9.3-next.3](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.2...merge-locales-v0.9.3-next.3) (2026-09-02)
137
+
138
+
139
+ ### Miscellaneous Chores
140
+
141
+ * **merge-locales:** Synchronize repo versions
142
+
143
+
144
+ ### Dependencies
145
+
146
+ * The following workspace dependencies were updated
147
+ * dependencies
148
+ * @twin.org/cli-core bumped from 0.9.3-next.2 to 0.9.3-next.3
149
+ * @twin.org/core bumped from 0.9.3-next.2 to 0.9.3-next.3
150
+ * @twin.org/nameof bumped from 0.9.3-next.2 to 0.9.3-next.3
151
+ * devDependencies
152
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.2 to 0.9.3-next.3
153
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.2 to 0.9.3-next.3
154
+
155
+ ## [0.9.3-next.2](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.1...merge-locales-v0.9.3-next.2) (2026-08-28)
156
+
157
+
158
+ ### Miscellaneous Chores
159
+
160
+ * **merge-locales:** Synchronize repo versions
161
+
162
+
163
+ ### Dependencies
164
+
165
+ * The following workspace dependencies were updated
166
+ * dependencies
167
+ * @twin.org/cli-core bumped from 0.9.3-next.1 to 0.9.3-next.2
168
+ * @twin.org/core bumped from 0.9.3-next.1 to 0.9.3-next.2
169
+ * @twin.org/nameof bumped from 0.9.3-next.1 to 0.9.3-next.2
170
+ * devDependencies
171
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.1 to 0.9.3-next.2
172
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.1 to 0.9.3-next.2
173
+
174
+ ## [0.9.3-next.1](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.3-next.0...merge-locales-v0.9.3-next.1) (2026-08-26)
175
+
176
+
177
+ ### Features
178
+
179
+ * add context id features ([#206](https://github.com/iotaledger/twin-framework/issues/206)) ([ef0d4ee](https://github.com/iotaledger/twin-framework/commit/ef0d4ee11a4f5fc6cc6f52a4958ce905c04ee13b))
180
+ * linting and dependency update ([676b4e9](https://github.com/iotaledger/twin-framework/commit/676b4e9d9bce158065200bbf875bb31da81d166d))
181
+ * locales validation ([#197](https://github.com/iotaledger/twin-framework/issues/197)) ([55fdadb](https://github.com/iotaledger/twin-framework/commit/55fdadb13595ce0047f787bd1d4135d429a99f12))
182
+ * typescript 6 update ([1d10f31](https://github.com/iotaledger/twin-framework/commit/1d10f31e6516ec622773f45e88af82fe749b384a))
183
+ * update dependencies ([4da77ab](https://github.com/iotaledger/twin-framework/commit/4da77ab30f499e52825ac5a76f51436ceb59c26e))
184
+
185
+
186
+ ### Bug Fixes
187
+
188
+ * ensure __decorate is defined for decorators ([103a563](https://github.com/iotaledger/twin-framework/commit/103a563ce01ebdef6240d2e590e7b026e8692684))
189
+
190
+
191
+ ### Dependencies
192
+
193
+ * The following workspace dependencies were updated
194
+ * dependencies
195
+ * @twin.org/cli-core bumped from 0.9.3-next.0 to 0.9.3-next.1
196
+ * @twin.org/core bumped from 0.9.3-next.0 to 0.9.3-next.1
197
+ * @twin.org/nameof bumped from 0.9.3-next.0 to 0.9.3-next.1
198
+ * devDependencies
199
+ * @twin.org/nameof-transformer bumped from 0.9.3-next.0 to 0.9.3-next.1
200
+ * @twin.org/nameof-vitest-plugin bumped from 0.9.3-next.0 to 0.9.3-next.1
201
+
3
202
  ## [0.9.2](https://github.com/iotaledger/twin-framework/compare/merge-locales-v0.9.2...merge-locales-v0.9.2) (2026-08-24)
4
203
 
5
204
 
package/locales/en.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "configJson": "Config JSON",
25
25
  "workingDirectory": "Working Directory",
26
26
  "outputDirectory": "Output Directory",
27
- "npmRoot": "NPM Root",
27
+ "packageNotFound": "Package Not Found",
28
28
  "sourcePackages": "Source Packages",
29
29
  "writingLocale": "Writing Locale",
30
30
  "mergingLocale": "Merging Locale"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twin.org/merge-locales",
3
- "version": "0.9.2",
3
+ "version": "0.9.3-next.10",
4
4
  "description": "Merge locale files from all dependencies",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,9 +14,9 @@
14
14
  "node": ">=24.0.0"
15
15
  },
16
16
  "dependencies": {
17
- "@twin.org/cli-core": "^0.9.2",
18
- "@twin.org/core": "^0.9.2",
19
- "@twin.org/nameof": "^0.9.2",
17
+ "@twin.org/cli-core": "0.9.3-next.10",
18
+ "@twin.org/core": "0.9.3-next.10",
19
+ "@twin.org/nameof": "0.9.3-next.10",
20
20
  "commander": "15.0.0",
21
21
  "glob": "13.0.6"
22
22
  },