Utilities
Build pending translation arguments, group completed results, and write files atomically.
The langnostic package exports four runtime helpers for custom plugins. Use
them with the types and hooks described in Plugin API.
buildTranslationStrings: Turn source values and changed-ID lists into pending arguments.buildTranslatedContentMap: Group completed translations by locale and message ID.writeFileAtomic: Replace a UTF-8 text file after writing its full contents.writeJsonAtomic: Format JSON and replace the destination file atomically.
buildTranslationStrings
import { buildTranslationStrings } from 'langnostic';
import type { TranslationFileMetadata } from 'langnostic';
const file: TranslationFileMetadata = {
source: { locale: 'en-US', path: 'messages/en-US.json' },
targets: [
{ locale: 'zh-CN', path: 'messages/zh-CN.json' },
{ locale: 'pt-BR', path: 'messages/pt-BR.json' },
],
};
export const pending = buildTranslationStrings(
{
welcome: { string: 'Welcome!', description: 'Greeting after sign-in' },
save: { string: 'Save' },
},
{ 'zh-CN': ['welcome', 'save'], 'pt-BR': ['save'] },
file,
);
| Parameter | Value |
|---|---|
content |
Readonly record of message IDs mapped to { string, description? } source values. |
changes |
Record of locales mapped to readonly arrays of IDs needing translation. |
file |
TranslationFileMetadata: source path and locale, plus configured target files. |
Returns ReadonlyArray<TranslationStringArg>. Each argument uses the source path
as batchId, the content key as id, and the source file’s locale. It retains
the source string and optional description.
The example returns two arguments: welcome for zh-CN, and save for both
zh-CN and pt-BR. A content ID is omitted when no configured target locale
lists it in changes. IDs absent from content and locales absent from
file.targets do not produce arguments. Target locale order follows
file.targets.
The helper does not read files or detect changes. Your plugin supplies the normalized content and per-locale changed-ID lists.
buildTranslatedContentMap
import { buildTranslatedContentMap } from 'langnostic';
import type { LangnosticPlugin } from 'langnostic';
type CompletedStrings = Parameters<
LangnosticPlugin['onTranslationBatchComplete']
>[0];
export function contentByLocale(results: CompletedStrings) {
return buildTranslatedContentMap(results);
}
Accepts the readonly completed-result array passed to
onTranslationBatchComplete() and returns
Map<TranslationLocale, Record<string, string>>.
For a result with id: 'welcome' and target
{ locale: 'zh-CN', string: '欢迎!' }, the returned map contains
'zh-CN' mapped to { welcome: '欢迎!' }. Empty input returns an empty map;
locales without translated values have no entry.
Only IDs and target strings are retained. The helper does not merge with existing
target files or retain source descriptions. batchId is not part of the map key,
so use it on a single batch when IDs repeat across files. If an ID and locale
appear more than once, the last value wins.
Atomic file writes
Call these helpers from write hooks, not during read-only discovery.
writeFileAtomic(filePath, content)
Accepts a destination path and string content, both typed as string, and
returns Promise<void>.
import { writeFileAtomic } from 'langnostic';
export async function writeDocument(path: string, markdown: string) {
await writeFileAtomic(path, markdown);
}
Creates missing parent directories and writes UTF-8 content to a temporary file beside the destination before renaming it into place. Existing file permissions are preserved. When the destination is a symlink, its resolved target is replaced and the symlink is preserved.
Write or rename failures reject the promise, and the temporary file is cleaned up. Atomic replacement applies to one file; a failure does not undo other files already written by a plugin.
writeJsonAtomic(filePath, value)
Accepts filePath: string and value: unknown, and returns Promise<void>.
import { writeJsonAtomic } from 'langnostic';
export async function writeCatalog(path: string) {
await writeJsonAtomic(path, { welcome: '欢迎!' });
}
Serializes the value with JSON.stringify(value, null, 2), appends a newline, and
passes the text to writeFileAtomic. Supply JSON-serializable values; serialization
errors reject the promise. This helper does not validate a catalog schema, sort
message IDs, or merge translations.