{"version":3,"sources":["../src/index.ts","../src/lib/init.ts","../src/lib/types.ts"],"sourcesContent":["export { default as i18next, type InitOptions, type TFunction, type TOptions, type TOptionsBase } from 'i18next';\nexport * from './lib';\n\nimport type { O } from '@ruffpuff/ts';\nimport type { CustomFunctionGet, CustomGet } from './lib/types';\n\ndeclare module 'i18next' {\n    export interface TFunction {\n        lng: string;\n        ns?: string;\n\n        <K extends string, TReturn>(key: CustomGet<K, TReturn>, options?: TOptionsBase | string): TReturn;\n        <K extends string, TReturn>(key: CustomGet<K, TReturn>, defaultValue: TReturn, options?: TOptionsBase | string): TReturn;\n        <K extends string, TArgs extends O, TReturn>(key: CustomFunctionGet<K, TArgs, TReturn>, options?: TOptions<TArgs>): TReturn;\n        <K extends string, TArgs extends O, TReturn>(key: CustomFunctionGet<K, TArgs, TReturn>, defaultValue: TReturn, options?: TOptions<TArgs>): TReturn;\n    }\n}\n","import Collection from '@discordjs/collection';\nimport { Locale, LocaleString } from 'discord-api-types/v10';\nimport i18next, { type InitOptions, type TFunction, getFixedT } from 'i18next';\nimport type { PathLike } from 'node:fs';\nimport { opendir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport backend from 'i18next-fs-backend';\n\nexport const discordLocales = new Set(Object.values(Locale)) as ReadonlySet<LocaleString>;\n\nexport function isDiscordLocale(lng: string): lng is LocaleString {\n    return discordLocales.has(lng as LocaleString);\n}\n\nexport const loadedLocales = new Set<string>();\nexport const loadedNamespaces = new Set<string>();\n\nexport const loadedPaths = new Set<string>();\nexport const formatters: Formatter[] = [];\n\nexport interface Formatter {\n    name: string;\n    format: (value: any, lng: string | undefined, options: any) => string;\n}\n\nexport function addFormatters(...formatters: Formatter[]): void {\n    formatters.push(...formatters);\n}\n\nexport async function init(options: InitOptions & { languageDirectory: string }) {\n    i18next.use(backend);\n    const languagesDir = options.languageDirectory;\n    await load(join(languagesDir));\n\n    await i18next.init({\n        ns: [...loadedNamespaces],\n        preload: [...loadedLocales],\n        initImmediate: false,\n        interpolation: {\n            escapeValue: false,\n            skipOnVariables: false,\n            ...options.interpolation\n        },\n        ignoreJSONStructure: false,\n        backend: {\n            loadPath: join(languagesDir, '{{lng}}', '{{ns}}.json'),\n            addPath: languagesDir\n        },\n        ...options\n    });\n\n    for (const { name, format } of formatters) {\n        i18next.services.formatter!.add(name, format);\n    }\n}\n\nexport async function load(directory: PathLike) {\n    const dir = await opendir(directory);\n    for await (const entry of dir) {\n        if (!entry.isDirectory()) continue;\n        loadedLocales.add(entry.name);\n        await loadLocale(join(dir.path, entry.name), '');\n    }\n\n    loadedPaths.add(dir.path);\n}\n\nasync function loadLocale(directory: string, ns: string) {\n    const dir = await opendir(directory);\n    for await (const entry of dir) {\n        if (entry.isDirectory()) {\n            await loadLocale(join(dir.path, entry.name), `${ns}${entry.name}/`);\n        } else if (entry.isFile() && entry.name.endsWith('.json')) {\n            loadedNamespaces.add(`${ns}${entry.name.slice(0, -5)}`);\n        }\n    }\n}\n\nconst cache = new Collection<string, TFunction>();\nexport function getT(locale: string) {\n    if (!loadedLocales.has(locale)) process.emitWarning(`could not find locale (${locale})`);\n    return cache.ensure(locale, () => getFixedT(locale));\n}\n","export type CustomGet<K extends string, TCustom> = K & { __type__: TCustom };\n\nexport function T<TCustom = string>(k: string): CustomGet<string, TCustom> {\n    return k as CustomGet<string, TCustom>;\n}\n\nexport type CustomFunctionGet<K extends string, TArgs, TReturn> = K & { __args__: TArgs; __return__: TReturn };\n\nexport function FT<TArgs, TReturn = string>(k: string): CustomFunctionGet<string, TArgs, TReturn> {\n    return k as CustomFunctionGet<string, TArgs, TReturn>;\n}\n"],"mappings":";;;;AAAA;;;ACAA;AACA;AACA;AAEA;AACA;AACA;AAEO,IAAM,iBAAiB,IAAI,IAAI,OAAO,OAAO,MAAM,CAAC;AAEpD,yBAAyB,KAAkC;AAC9D,SAAO,eAAe,IAAI,GAAG;;AADjB;AAIT,IAAM,gBAAgB,oBAAI,IAAG;AAC7B,IAAM,mBAAmB,oBAAI,IAAG;AAEhC,IAAM,cAAc,oBAAI,IAAG;AAC3B,IAAM,aAA0B,CAAA;AAOhC,0BAA0B,aAA+B;AAC5D,cAAW,KAAI,GAAI,WAAU;;AADjB;AAIhB,oBAA2B,SAAsD;AAC7E,UAAQ,IAAI,OAAO;AACnB,QAAM,eAAe,QAAQ;AAC7B,QAAM,KAAK,KAAK,YAAY,CAAC;AAE7B,QAAM,QAAQ,KAAK;IACf,IAAI;SAAI;;IACR,SAAS;SAAI;;IACb,eAAe;IACf,eAAe;MACX,aAAa;MACb,iBAAiB;SACd,QAAQ;;IAEf,qBAAqB;IACrB,SAAS;MACL,UAAU,KAAK,cAAc,WAAW,aAAa;MACrD,SAAS;;OAEV;GACN;AAED,aAAW,EAAE,MAAM,YAAY,YAAY;AACvC,YAAQ,SAAS,UAAW,IAAI,MAAM,MAAM;;;AAvB9B;AA2BtB,oBAA2B,WAAqB;AAC5C,QAAM,MAAM,MAAM,QAAQ,SAAS;AACnC,mBAAiB,SAAS,KAAK;AAC3B,QAAI,CAAC,MAAM,YAAW;AAAI;AAC1B,kBAAc,IAAI,MAAM,IAAI;AAC5B,UAAM,WAAW,KAAK,IAAI,MAAM,MAAM,IAAI,GAAG,EAAE;;AAGnD,cAAY,IAAI,IAAI,IAAI;;AARN;AAWtB,0BAA0B,WAAmB,IAAY;AACrD,QAAM,MAAM,MAAM,QAAQ,SAAS;AACnC,mBAAiB,SAAS,KAAK;AAC3B,QAAI,MAAM,YAAW,GAAI;AACrB,YAAM,WAAW,KAAK,IAAI,MAAM,MAAM,IAAI,GAAG,GAAG,KAAK,MAAM,OAAO;eAC3D,MAAM,OAAM,KAAM,MAAM,KAAK,SAAS,OAAO,GAAG;AACvD,uBAAiB,IAAI,GAAG,KAAK,MAAM,KAAK,MAAM,GAAG,EAAE,GAAG;;;;AANnD;AAWf,IAAM,QAAQ,IAAI,WAAU;AACrB,cAAc,QAAgB;AACjC,MAAI,CAAC,cAAc,IAAI,MAAM;AAAG,YAAQ,YAAY,0BAA0B,SAAS;AACvF,SAAO,MAAM,OAAO,QAAQ,MAAM,UAAU,MAAM,CAAC;;AAFvC;;;AC7ET,WAA6B,GAAuC;AACvE,SAAO;;AADK;AAMT,YAAqC,GAAsD;AAC9F,SAAO;;AADK;","names":[]}