From 3d12841efa39ea6a059a06d769a343c3c37a748c Mon Sep 17 00:00:00 2001 From: Timofei Iatsenko Date: Thu, 16 Jan 2025 11:34:39 +0100 Subject: [PATCH] refactor: remove ramda --- package.json | 1 - packages/cli/package.json | 1 - packages/cli/src/api/catalog.test.ts | 6 +- packages/cli/src/api/catalog.ts | 64 +++++++-------- packages/cli/src/api/catalog/mergeCatalog.ts | 78 ++++++++++--------- packages/cli/src/api/pseudoLocalize.ts | 11 +-- .../src/extract-experimental/writeCatalogs.ts | 2 +- packages/format-json/package.json | 3 +- packages/format-json/src/json.ts | 60 +++++++++----- packages/remote-loader/package.json | 3 +- packages/remote-loader/src/index.ts | 22 +++--- packages/remote-loader/src/minimalParser.ts | 22 +++--- yarn.lock | 34 -------- 13 files changed, 143 insertions(+), 164 deletions(-) diff --git a/package.json b/package.json index edb451308..c95b61f47 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "@types/jest": "^29.4.0", "@types/mock-fs": "^4.13.1", "@types/node": "20.14.8", - "@types/ramda": "^0.27.23", "babel-jest": "^29.7.0", "chalk": "^4.1.0", "cross-env": "^7.0.2", diff --git a/packages/cli/package.json b/packages/cli/package.json index 16824b3a1..3bf5142d1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -80,7 +80,6 @@ "pkg-up": "^3.1.0", "pofile": "^1.1.4", "pseudolocale": "^2.0.0", - "ramda": "^0.27.1", "source-map": "^0.8.0-beta.0" }, "devDependencies": { diff --git a/packages/cli/src/api/catalog.test.ts b/packages/cli/src/api/catalog.test.ts index fef43270c..e8b2152fe 100644 --- a/packages/cli/src/api/catalog.test.ts +++ b/packages/cli/src/api/catalog.test.ts @@ -528,7 +528,7 @@ describe("order", () => { }), } - const orderedCatalogs = order("messageId")(catalog) + const orderedCatalogs = order("messageId", catalog) // Test that the message content is the same as before expect(orderedCatalogs).toMatchSnapshot() @@ -560,7 +560,7 @@ describe("order", () => { }), } - const orderedCatalogs = order("origin")(catalog) + const orderedCatalogs = order("origin", catalog) // Test that the message content is the same as before expect(orderedCatalogs).toMatchSnapshot() @@ -596,7 +596,7 @@ describe("order", () => { }), } - const orderedCatalogs = order("message")(catalog) + const orderedCatalogs = order("message", catalog) // Jest snapshot order the keys automatically, so test that the key order explicitly expect(Object.keys(orderedCatalogs)).toMatchInlineSnapshot(` diff --git a/packages/cli/src/api/catalog.ts b/packages/cli/src/api/catalog.ts index 7b0e02b6f..2703c67a3 100644 --- a/packages/cli/src/api/catalog.ts +++ b/packages/cli/src/api/catalog.ts @@ -1,6 +1,5 @@ import fs from "fs" import path from "path" -import * as R from "ramda" import { globSync } from "glob" import normalize from "normalize-path" @@ -23,12 +22,7 @@ import { replacePlaceholders, writeFile, } from "./utils" -import { - AllCatalogsType, - CatalogType, - ExtractedCatalogType, - ExtractedMessageType, -} from "./types" +import { AllCatalogsType, CatalogType, ExtractedCatalogType } from "./types" const LOCALE = "{locale}" const LOCALE_SUFFIX_RE = /\{locale\}.*$/ @@ -95,16 +89,17 @@ export class Catalog { }) // Map over all locales and post-process each catalog - const cleanAndSort = R.map( - R.pipe( - // Clean obsolete messages - (options.clean ? cleanObsolete : R.identity) as any, - // Sort messages - order(options.orderBy) - ) - ) as unknown as (catalog: AllCatalogsType) => AllCatalogsType + const sortedCatalogs = Object.fromEntries( + Object.entries(catalogs).map(([locale, catalog]) => { + if (options.clean) { + catalog = cleanObsolete(catalog) + } - const sortedCatalogs = cleanAndSort(catalogs) + catalog = order(options.orderBy, catalog) + + return [locale, catalog] + }) + ) as AllCatalogsType const locales = options.locale ? options.locale : this.locales await Promise.all( @@ -119,7 +114,7 @@ export class Catalog { ): Promise { const catalog = await this.collect({ files: options.files }) if (!catalog) return false - const sorted = order(options.orderBy)(catalog as CatalogType) + const sorted = order(options.orderBy, catalog as CatalogType) await this.writeTemplate(sorted) return sorted @@ -169,14 +164,17 @@ export class Catalog { nextCatalog: ExtractedCatalogType, options: MergeOptions ) { - return R.mapObjIndexed((prevCatalog, locale) => { - return mergeCatalog( - prevCatalog, - nextCatalog, - this.config.sourceLocale === locale, - options - ) - }, prevCatalogs) + return Object.fromEntries( + Object.entries(prevCatalogs).map(([locale, prevCatalog]) => [ + locale, + mergeCatalog( + prevCatalog, + nextCatalog, + this.config.sourceLocale === locale, + options + ), + ]) + ) } async getTranslations(locale: string, options: GetTranslationsOptions) { @@ -287,20 +285,22 @@ function getTemplatePath(ext: string, path: string) { return path.replace(LOCALE_SUFFIX_RE, "messages" + ext) } -export const cleanObsolete = R.filter( - (message: ExtractedMessageType) => !message.obsolete -) +export function cleanObsolete(messages: T): T { + return Object.fromEntries( + Object.entries(messages).filter(([, message]) => !message.obsolete) + ) as T +} export function order( - by: OrderBy -): (catalog: T) => T { + by: OrderBy, + catalog: T +): T { return { messageId: orderByMessageId, message: orderByMessage, origin: orderByOrigin, - }[by] + }[by](catalog) } - /** * Object keys are in the same order as they were created * https://stackoverflow.com/a/31102605/1535540 diff --git a/packages/cli/src/api/catalog/mergeCatalog.ts b/packages/cli/src/api/catalog/mergeCatalog.ts index 73b1a1f81..c00881aa1 100644 --- a/packages/cli/src/api/catalog/mergeCatalog.ts +++ b/packages/cli/src/api/catalog/mergeCatalog.ts @@ -1,6 +1,5 @@ -import * as R from "ramda" import type { MergeOptions } from "../catalog" -import { CatalogType, ExtractedCatalogType, MessageType } from "../types" +import { CatalogType, ExtractedCatalogType } from "../types" export function mergeCatalog( prevCatalog: CatalogType, @@ -9,49 +8,52 @@ export function mergeCatalog( options: MergeOptions ): CatalogType { const nextKeys = Object.keys(nextCatalog) + const prevKeys = Object.keys(prevCatalog || {}) - const prevKeys = R.keys(prevCatalog).map(String) - - const newKeys = R.difference(nextKeys, prevKeys) - const mergeKeys = R.intersection(nextKeys, prevKeys) - const obsoleteKeys = R.difference(prevKeys, nextKeys) + const newKeys = nextKeys.filter((key) => !prevKeys.includes(key)) + const mergeKeys = nextKeys.filter((key) => prevKeys.includes(key)) + const obsoleteKeys = prevKeys.filter((key) => !nextKeys.includes(key)) // Initialize new catalog with new keys - const newMessages = R.mapObjIndexed( - (message: MessageType, key) => ({ - translation: forSourceLocale ? message.message || key : "", - ...message, - }), - R.pick(newKeys, nextCatalog) + const newMessages: CatalogType = Object.fromEntries( + newKeys.map((key) => [ + key, + { + translation: forSourceLocale ? nextCatalog[key].message || key : "", + ...nextCatalog[key], + }, + ]) ) // Merge translations from previous catalog - const mergedMessages = mergeKeys.map((key) => { - const updateFromDefaults = - forSourceLocale && - (prevCatalog[key].translation === prevCatalog[key].message || - options.overwrite) - - const translation = updateFromDefaults - ? nextCatalog[key].message || key - : prevCatalog[key].translation - - return { - [key]: { - translation, - ...R.omit(["obsolete, translation"], nextCatalog[key]), - }, - } - }) + const mergedMessages = Object.fromEntries( + mergeKeys.map((key) => { + const updateFromDefaults = + forSourceLocale && + (prevCatalog[key].translation === prevCatalog[key].message || + options.overwrite) + + const translation = updateFromDefaults + ? nextCatalog[key].message || key + : prevCatalog[key].translation + + const { obsolete, ...rest } = nextCatalog[key] + + return [key, { ...rest, translation }] + }) + ) // Mark all remaining translations as obsolete // Only if *options.files* is not provided - const obsoleteMessages = obsoleteKeys.map((key) => ({ - [key]: { - ...prevCatalog[key], - ...(!options.files && { obsolete: true }), - }, - })) - - return R.mergeAll([newMessages, ...mergedMessages, ...obsoleteMessages]) + const obsoleteMessages = Object.fromEntries( + obsoleteKeys.map((key) => [ + key, + { + ...prevCatalog[key], + ...(options.files ? {} : { obsolete: true }), + }, + ]) + ) + + return { ...newMessages, ...mergedMessages, ...obsoleteMessages } } diff --git a/packages/cli/src/api/pseudoLocalize.ts b/packages/cli/src/api/pseudoLocalize.ts index 51f79f802..891dd197b 100644 --- a/packages/cli/src/api/pseudoLocalize.ts +++ b/packages/cli/src/api/pseudoLocalize.ts @@ -1,4 +1,3 @@ -import R from "ramda" import pseudolocale from "pseudolocale" const delimiter = "%&&&%" @@ -45,18 +44,14 @@ function addDelimitersVariables(message: string) { }) } -const addDelimiters = R.compose( - addDelimitersVariables, - addDelimitersMacro, - addDelimitersHTMLTags -) - function removeDelimiters(message: string) { return message.replace(new RegExp(delimiter, "g"), "") } export default function (message: string) { - message = addDelimiters(message) + message = addDelimitersHTMLTags(message) + message = addDelimitersMacro(message) + message = addDelimitersVariables(message) message = pseudolocale(message, { delimiter, prepend: "", diff --git a/packages/cli/src/extract-experimental/writeCatalogs.ts b/packages/cli/src/extract-experimental/writeCatalogs.ts index c5cecf620..4648aa12b 100644 --- a/packages/cli/src/extract-experimental/writeCatalogs.ts +++ b/packages/cli/src/extract-experimental/writeCatalogs.ts @@ -30,7 +30,7 @@ function cleanAndSort(catalog: CatalogType, clean: boolean, orderBy: OrderBy) { catalog = cleanObsolete(catalog) } - return order(orderBy)(catalog) as CatalogType + return order(orderBy, catalog) as CatalogType } export async function writeCatalogs( diff --git a/packages/format-json/package.json b/packages/format-json/package.json index f274885ab..4c0f599a5 100644 --- a/packages/format-json/package.json +++ b/packages/format-json/package.json @@ -39,8 +39,7 @@ "dist/" ], "dependencies": { - "@lingui/conf": "5.1.2", - "ramda": "^0.28.0" + "@lingui/conf": "5.1.2" }, "devDependencies": { "tsd": "^0.28.0", diff --git a/packages/format-json/src/json.ts b/packages/format-json/src/json.ts index b9684c45b..fe138ff41 100644 --- a/packages/format-json/src/json.ts +++ b/packages/format-json/src/json.ts @@ -1,10 +1,7 @@ -import * as R from "ramda" - import { CatalogFormatter, CatalogType, ExtractedMessageType, - MessageType, } from "@lingui/conf" export type JsonFormatterOptions = { @@ -43,27 +40,50 @@ type NoOriginsCatalogType = { type MinimalCatalogType = Record -const serializeMinimal = R.map( - (message: MessageType) => message.translation || "" -) as unknown as (catalog: CatalogType) => MinimalCatalogType +const serializeMinimal = (catalog: CatalogType): MinimalCatalogType => { + const result: MinimalCatalogType = {} + for (const key in catalog) { + result[key] = catalog[key].translation || "" + } + return result +} -const deserializeMinimal = R.map((translation: string) => ({ - translation, - obsolete: false, - message: null, - origin: [], -})) as unknown as (minimalCatalog: MinimalCatalogType) => CatalogType +const deserializeMinimal = ( + minimalCatalog: MinimalCatalogType +): CatalogType => { + const result: CatalogType = {} + for (const key in minimalCatalog) { + result[key] = { + translation: minimalCatalog[key], + obsolete: false, + message: null, + origin: [], + } + } + return result +} -const removeOrigins = R.map(({ origin, ...message }) => message) as unknown as ( - catalog: CatalogType -) => NoOriginsCatalogType +const removeOrigins = (catalog: CatalogType): NoOriginsCatalogType => { + const result: NoOriginsCatalogType = {} + for (const key in catalog) { + const { origin, ...message } = catalog[key] + result[key] = message + } + return result +} -const removeLineNumbers = R.map((message: ExtractedMessageType) => { - if (message.origin) { - message.origin = message.origin.map(([file]) => [file]) +const removeLineNumbers = ( + catalog: ExtractedMessageType +): NoOriginsCatalogType => { + const result: NoOriginsCatalogType = {} + for (const key in catalog) { + result[key] = { + ...catalog[key], + origin: catalog[key].origin?.map(([file]) => [file]), + } } - return message -}) as unknown as (catalog: ExtractedMessageType) => NoOriginsCatalogType + return result +} export function formatter( options: JsonFormatterOptions = {} diff --git a/packages/remote-loader/package.json b/packages/remote-loader/package.json index 169a8a457..d733fb4f8 100644 --- a/packages/remote-loader/package.json +++ b/packages/remote-loader/package.json @@ -50,8 +50,7 @@ ], "dependencies": { "@lingui/core": "4.0.0", - "@lingui/message-utils": "4.0.0", - "ramda": "^0.27.1" + "@lingui/message-utils": "4.0.0" }, "devDependencies": { "unbuild": "2.0.0" diff --git a/packages/remote-loader/src/index.ts b/packages/remote-loader/src/index.ts index eca784c32..221c02a0e 100644 --- a/packages/remote-loader/src/index.ts +++ b/packages/remote-loader/src/index.ts @@ -1,4 +1,3 @@ -import * as R from "ramda" import { createBrowserCompiledCatalog } from "./browserCompiler" import PARSERS from "./minimalParser" @@ -8,7 +7,7 @@ type RemoteLoaderOpts = { messages: string | Record | T } -function remoteLoader({ +export function remoteLoader({ format = "minimal", fallbackMessages, messages, @@ -35,19 +34,16 @@ function remoteLoader({ `) } - const mapTranslationsToInterporlatedString = R.mapObjIndexed((_, key) => { + const mapTranslationsToInterpolatedString = Object.fromEntries( // if there's fallback and translation is empty, return the fallback - if ( + Object.keys(parsedMessages).map((key) => [ + key, parsedMessages[key].translation === "" && parsedFallbackMessages?.[key]?.translation - ) { - return parsedFallbackMessages[key].translation - } - - return parsedMessages[key].translation - }, parsedMessages) + ? parsedFallbackMessages[key].translation + : parsedMessages[key].translation, + ]) + ) - return createBrowserCompiledCatalog(mapTranslationsToInterporlatedString) + return createBrowserCompiledCatalog(mapTranslationsToInterpolatedString) } - -export { remoteLoader } diff --git a/packages/remote-loader/src/minimalParser.ts b/packages/remote-loader/src/minimalParser.ts index 4be4683b7..5cf175e13 100644 --- a/packages/remote-loader/src/minimalParser.ts +++ b/packages/remote-loader/src/minimalParser.ts @@ -1,15 +1,19 @@ -import * as R from "ramda" - -const deserialize = R.map((translation: string) => ({ - translation, - obsolete: false, - message: null, - origin: [], -})) as unknown as (minimalCatalog: any) => any +const deserialize = (minimalCatalog: Record) => { + const result: Record = {} + for (const key in minimalCatalog) { + result[key] = { + translation: minimalCatalog[key], + obsolete: false, + message: null, + origin: [], + } + } + return result +} const PARSERS = { minimal: (content: Record | T) => { - return deserialize(content) + return deserialize(content as Record) }, } diff --git a/yarn.lock b/yarn.lock index 94acd59dd..ad58ec958 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2684,7 +2684,6 @@ __metadata: pkg-up: ^3.1.0 pofile: ^1.1.4 pseudolocale: ^2.0.0 - ramda: ^0.27.1 source-map: ^0.8.0-beta.0 bin: lingui: ./dist/lingui.js @@ -2775,7 +2774,6 @@ __metadata: resolution: "@lingui/format-json@workspace:packages/format-json" dependencies: "@lingui/conf": 5.1.2 - ramda: ^0.28.0 tsd: ^0.28.0 unbuild: ^2.0.0 languageName: unknown @@ -2934,7 +2932,6 @@ __metadata: dependencies: "@lingui/core": 4.0.0 "@lingui/message-utils": 4.0.0 - ramda: ^0.27.1 unbuild: 2.0.0 languageName: unknown linkType: soft @@ -4318,15 +4315,6 @@ __metadata: languageName: node linkType: hard -"@types/ramda@npm:^0.27.23": - version: 0.27.23 - resolution: "@types/ramda@npm:0.27.23" - dependencies: - ts-toolbelt: ^6.3.3 - checksum: cb551b6b44adbb40426ed5fde35104cd05850077e0c78c33bccd555156c3a9768f02186c57576d1806d238b517fcb2b6ef5fb472d43261865562ac9647e997b8 - languageName: node - linkType: hard - "@types/react-dom@npm:^18.0.0": version: 18.2.6 resolution: "@types/react-dom@npm:18.2.6" @@ -10624,7 +10612,6 @@ __metadata: "@types/jest": ^29.4.0 "@types/mock-fs": ^4.13.1 "@types/node": 20.14.8 - "@types/ramda": ^0.27.23 babel-jest: ^29.7.0 chalk: ^4.1.0 cross-env: ^7.0.2 @@ -13453,20 +13440,6 @@ __metadata: languageName: node linkType: hard -"ramda@npm:^0.27.1": - version: 0.27.2 - resolution: "ramda@npm:0.27.2" - checksum: 28d6735dd1eea1a796c56cf6111f3673c6105bbd736e521cdd7826c46a18eeff337c2dba4668f6eed990d539b9961fd6db19aa46ccc1530ba67a396c0a9f580d - languageName: node - linkType: hard - -"ramda@npm:^0.28.0": - version: 0.28.0 - resolution: "ramda@npm:0.28.0" - checksum: 44ea6e5010bba70151b6a92d8114a91915e8b5a16105cce65fae58c9d7386b812c429645e35f21141d7087568550ce383bc10ee1a65cdec951f4b69ea457e6a4 - languageName: node - linkType: hard - "randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -15322,13 +15295,6 @@ __metadata: languageName: node linkType: hard -"ts-toolbelt@npm:^6.3.3": - version: 6.15.5 - resolution: "ts-toolbelt@npm:6.15.5" - checksum: 24ad00cfd9ce735c76c873a9b1347eac475b94e39ebbdf100c9019dce88dd5f4babed52884cf82bb456a38c28edd0099ab6f704b84b2e5e034852b618472c1f3 - languageName: node - linkType: hard - "tsconfig-paths@npm:^3.15.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0"