Skip to content

Instantly share code, notes, and snippets.

@thekip
Created June 23, 2023 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thekip/7ef13a5f6bae83f5550166a51a1e426e to your computer and use it in GitHub Desktop.
Save thekip/7ef13a5f6bae83f5550166a51a1e426e to your computer and use it in GitHub Desktop.
Convert explicit ids from v3 catalogs to v4
# Run it in the place where is your `lingui.config` is located
# ts-node ./migrate.ts
import {
CatalogType,
ExtractedMessageType,
getConfig,
LinguiConfigNormalized,
MessageType,
} from "@lingui/conf"
import { getCatalogs } from "@lingui/cli/api"
import { formatter as createFormatter } from "@lingui/format-po"
import fs from "fs/promises"
import { generateMessageId } from "@lingui/message-utils/generateMessageId"
function _isGeneratedId(id: string, message: ExtractedMessageType): boolean {
return id === generateMessageId(message.message, message.context)
}
async function command(
config: LinguiConfigNormalized,
) {
const catalogs = await getCatalogs(config)
const formatter = createFormatter({
explicitIdAsDefault: true,
})
await Promise.all(
catalogs.map(async (catalog) => {
const extractedCatalog = await catalog.collect()
for (const locale of config.locales) {
const translationFileName = catalog.getFilename(locale)
const translationCatalog = await formatter.parse(
await fs.readFile(translationFileName, "utf-8"),
{
locale,
sourceLocale: config.sourceLocale,
filename: translationFileName,
}
)
for (const messageId in extractedCatalog) {
const extractedMessage = extractedCatalog[messageId]
const isGeneratedId = _isGeneratedId(messageId, extractedMessage)
const oldId = isGeneratedId ? extractedMessage.message : messageId
if (translationCatalog[oldId]) {
;(extractedMessage as MessageType).translation =
translationCatalog[oldId].translation
}
}
await catalog.write(locale, extractedCatalog as CatalogType)
}
})
)
}
command(getConfig())
@thekip
Copy link
Author

thekip commented Jun 23, 2023

Please leave your feedback here. I will try to keep this gist updated.

@MarttiR
Copy link

MarttiR commented Aug 22, 2023

Thanks for this, saved my day! 🥇

The following is an adaptation to

  • run on plain node instead of ts-node, and
  • convert legacy lingui format JSON files.
const {
  getConfig,
} = require("@lingui/conf");

const { getCatalogs } = require("@lingui/cli/api");
const { formatter: createFormatter } = require("@lingui/format-json");
const fs = require("fs/promises");
const { generateMessageId } = require("@lingui/message-utils/generateMessageId");

function _isGeneratedId(id, message) {
  return id === generateMessageId(message.message, message.context);
}

async function command(config) {
  const catalogs = await getCatalogs(config);

  const formatter = createFormatter({
    explicitIdAsDefault: true,
  });

  await Promise.all(
    catalogs.map(async (catalog) => {
      const extractedCatalog = await catalog.collect();

      for (const locale of config.locales) {
        const translationFileName = catalog.getFilename(locale);

        const translationCatalog = await formatter.parse(
          await fs.readFile(translationFileName, "utf-8"),
          {
            locale,
            sourceLocale: config.sourceLocale,
            filename: translationFileName,
          }
        );

        for (const messageId in extractedCatalog) {
          const extractedMessage = extractedCatalog[messageId];

          const isGeneratedId = _isGeneratedId(messageId, extractedMessage);
          const oldId = isGeneratedId ? extractedMessage.message : messageId;

          if (translationCatalog[oldId]) {
            extractedMessage.translation =
              translationCatalog[oldId].translation;
          }
        }

        await catalog.write(locale, extractedCatalog);
      }
    })
  );
}

command(getConfig());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment