mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2025-12-19 10:07:46 -05:00
116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
import { writeFileSync, readdirSync, lstatSync } from 'fs';
|
|
import { join, resolve } from 'path';
|
|
import algoliasearch from 'algoliasearch';
|
|
import i18n from 'i18next';
|
|
import backend from 'i18next-fs-backend';
|
|
|
|
import {
|
|
algoliaAppId,
|
|
algoliaAPIKey,
|
|
clientLocale,
|
|
environment
|
|
} from '../config/env.json';
|
|
import { newsIndex } from '../src/utils/algolia-locale-setup';
|
|
import { i18nextCodes } from '../../shared-dist/config/i18n';
|
|
|
|
const i18nextCode = i18nextCodes[clientLocale as keyof typeof i18nextCodes];
|
|
|
|
i18n
|
|
.use(backend)
|
|
.init({
|
|
defaultNS: 'translations',
|
|
fallbackLng: 'en',
|
|
interpolation: {
|
|
escapeValue: false
|
|
},
|
|
initImmediate: false,
|
|
preload: readdirSync(join(__dirname, '../i18n/locales')).filter(
|
|
fileName => {
|
|
const joinedPath = join(join(__dirname, '../i18n/locales'), fileName);
|
|
const isDirectory = lstatSync(joinedPath).isDirectory();
|
|
return isDirectory;
|
|
}
|
|
),
|
|
lng: i18nextCode,
|
|
ns: ['translations'],
|
|
backend: {
|
|
loadPath: resolve(
|
|
__dirname,
|
|
`../i18n/locales/${clientLocale}/translations.json`
|
|
)
|
|
}
|
|
})
|
|
.catch((error: Error) => {
|
|
throw Error(error.message);
|
|
});
|
|
|
|
const t = i18n.t.bind(i18n);
|
|
|
|
export const roundDownToNearestHundred = (num: number) =>
|
|
Math.floor(num / 100) * 100;
|
|
|
|
export const convertToLocalizedString = (num: number, ISOCode: string) =>
|
|
num.toLocaleString(ISOCode);
|
|
|
|
interface GenerateSearchPlaceholderOptions {
|
|
locale?: string;
|
|
mockRecordsNum?: number;
|
|
}
|
|
|
|
export const generateSearchPlaceholder = async (
|
|
options: GenerateSearchPlaceholderOptions = {}
|
|
) => {
|
|
const { locale, mockRecordsNum } = options;
|
|
let placeholderText = t('search.placeholder.default');
|
|
|
|
try {
|
|
let totalRecords = mockRecordsNum || 0;
|
|
if (!mockRecordsNum) {
|
|
const algoliaClient = algoliasearch(algoliaAppId, algoliaAPIKey);
|
|
const index = algoliaClient.initIndex(newsIndex);
|
|
const res = await index.search('');
|
|
totalRecords = res.nbHits;
|
|
}
|
|
const roundedTotalRecords = roundDownToNearestHundred(totalRecords);
|
|
|
|
if (roundedTotalRecords >= 100) {
|
|
placeholderText = i18n.t('search.placeholder.numbered', {
|
|
roundedTotalRecords: convertToLocalizedString(
|
|
roundedTotalRecords,
|
|
i18nextCode
|
|
)
|
|
});
|
|
}
|
|
} catch (_err) {
|
|
if (environment === 'production') {
|
|
console.warn(`
|
|
----------------------------------------------------------
|
|
Warning: Could not get the total number of Algolia records
|
|
----------------------------------------------------------
|
|
Make sure that Algolia keys and index are set up correctly.
|
|
|
|
Falling back to the default search placeholder text.
|
|
----------------------------------------------------------
|
|
`);
|
|
}
|
|
}
|
|
|
|
writeFileSync(
|
|
resolve(
|
|
__dirname,
|
|
`../i18n/locales/${locale ? locale : clientLocale}/search-bar.json`
|
|
),
|
|
JSON.stringify({
|
|
placeholder: placeholderText
|
|
})
|
|
);
|
|
|
|
return placeholderText; // for testing
|
|
};
|
|
|
|
void generateSearchPlaceholder();
|
|
// TODO: remove the need to fallback to english once we're confident it's
|
|
// unnecessary (client/i18n/config.js will need all references to 'en' removing)
|
|
if (clientLocale !== 'english')
|
|
void generateSearchPlaceholder({ locale: 'english' });
|