next-intl
Version:
Internationalization (i18n) for Next.js
71 lines (65 loc) • 2.36 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { once, throwError } from '../utils.js';
import watchFile from '../watchFile.js';
const runOnce = once('_NEXT_INTL_COMPILE_MESSAGES');
function createMessagesDeclaration(messagesPaths) {
// Instead of running _only_ in certain cases, it's
// safer to _avoid_ running for certain known cases.
// https://github.com/amannn/next-intl/issues/2006
const shouldBailOut = ['info', 'start'
// Note: These commands don't consult the
// Next.js config, so we can't detect them here.
// - telemetry
// - lint
//
// What remains are:
// - dev
// - build
// - typegen
].some(arg => process.argv.includes(arg));
if (shouldBailOut) {
return;
}
runOnce(() => {
for (const messagesPath of messagesPaths) {
const fullPath = path.resolve(messagesPath);
if (!fs.existsSync(fullPath)) {
throwError(`\`createMessagesDeclaration\` points to a non-existent file: ${fullPath}`);
}
if (!fullPath.endsWith('.json')) {
throwError(`\`createMessagesDeclaration\` needs to point to a JSON file. Received: ${fullPath}`);
}
// Keep this as a runtime check and don't replace
// this with a constant during the build process
const env = process.env['NODE_ENV'.trim()];
compileDeclaration(messagesPath);
if (env === 'development') {
startWatching(messagesPath);
}
}
});
}
function startWatching(messagesPath) {
const watcher = watchFile(messagesPath, () => {
compileDeclaration(messagesPath, true);
});
process.on('exit', () => {
watcher.close();
});
}
function compileDeclaration(messagesPath, async = false) {
const declarationPath = messagesPath.replace(/\.json$/, '.d.json.ts');
function createDeclaration(content) {
return `// This file is auto-generated by next-intl, do not edit directly.
// See: https://next-intl.dev/docs/workflows/typescript#messages-arguments
declare const messages: ${content.trim()};
export default messages;`;
}
if (async) {
return fs.promises.readFile(messagesPath, 'utf-8').then(content => fs.promises.writeFile(declarationPath, createDeclaration(content)));
}
const content = fs.readFileSync(messagesPath, 'utf-8');
fs.writeFileSync(declarationPath, createDeclaration(content));
}
export { createMessagesDeclaration as default };