UNPKG

react-native-localize

Version:

A toolbox for your React Native app localization.

110 lines (91 loc) 2.9 kB
import * as Expo from "@expo/config-plugins"; import { mergeContents } from "@expo/config-plugins/build/utils/generateCode"; import { mkdirSync, writeFileSync } from "fs"; import { join } from "path"; const PACKAGE_NAME = "react-native-localize"; type Props = { locales?: string[] | { android?: string[]; ios?: string[] }; }; const withIosAppLocales: Expo.ConfigPlugin<string[]> = ( { ios = {}, ...config }, locales, ) => ({ ...config, ios: { ...ios, infoPlist: { CFBundleLocalizations: locales } }, }); const withAndroidAppLocales: Expo.ConfigPlugin<string[]> = ( config, locales, ) => { const withLocalesConfig = Expo.withDangerousMod(config, [ "android", (config) => { const xmlDir = join( config.modRequest.platformProjectRoot, "app", "src", "main", "res", "xml", ); mkdirSync(xmlDir, { recursive: true }); writeFileSync( join(xmlDir, "locales_config.xml"), `<?xml version="1.0" encoding="utf-8"?> <locale-config xmlns:android="http://schemas.android.com/apk/res/android"> ${locales.map((locale) => ` <locale android:name="${locale}"/>`).join("\n")} </locale-config> `, ); return config; }, ]); const withMainApplication = Expo.withAndroidManifest( withLocalesConfig, (config) => { const mainApplication = Expo.AndroidConfig.Manifest.getMainApplicationOrThrow( config.modResults, ); mainApplication.$ = { ...mainApplication.$, "android:localeConfig": "@xml/locales_config", }; return config; }, ); return Expo.withAppBuildGradle(withMainApplication, (config) => { const { modResults } = config; const list = locales.map((lang) => `"${lang}"`).join(", "); const { contents } = mergeContents({ src: modResults.contents, comment: "//", tag: PACKAGE_NAME, offset: 1, anchor: /versionName "[\d.]+"/, newSrc: ` resourceConfigurations += ${modResults.language === "kt" ? `listOf(${list})` : `[${list}]`}`, }); return { ...config, modResults: { ...modResults, contents }, }; }); }; const withAppLocales: Expo.ConfigPlugin<Props | undefined> = ( config, { locales = [] } = {}, ) => { const plugins: Array<[Expo.ConfigPlugin<string[]>, string[]]> = []; const { platforms = [] } = config; const { android, ios } = Array.isArray(locales) ? { android: locales, ios: locales } : { android: locales.android ?? [], ios: locales.ios ?? [] }; if (platforms.includes("ios") && ios.length > 0) { plugins.push([withIosAppLocales, ios]); } if (platforms.includes("android") && android.length > 0) { plugins.push([withAndroidAppLocales, android]); } return Expo.withPlugins(config, plugins); }; export default Expo.createRunOncePlugin(withAppLocales, PACKAGE_NAME);