@sapphire/plugin-i18next 8.0.0-next.fe39124 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/lib/functions.cjs +1 -1
- package/dist/cjs/lib/functions.cjs.map +1 -1
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/lib/functions.mjs +1 -1
- package/dist/esm/lib/functions.mjs.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
# [@sapphire/plugin-i18next@8.0.0](https://github.com/sapphiredev/plugins/compare/@sapphire/plugin-i18next@7.1.3...@sapphire/plugin-i18next@8.0.0) - (2025-05-12)
|
|
6
|
+
|
|
7
|
+
## 🐛 Bug Fixes
|
|
8
|
+
|
|
9
|
+
- **deps:** Update dependency i18next to v25 ([b4041d6](https://github.com/sapphiredev/plugins/commit/b4041d680c9946ef38e663de2caf00f218b78a03)) ([#738](https://github.com/sapphiredev/plugins/pull/738) by @renovate[bot])
|
|
10
|
+
- 💥 **Co-authored-by:** renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
|
|
11
|
+
- **deps:** Update all non-major dependencies ([214f8ce](https://github.com/sapphiredev/plugins/commit/214f8cec2dd7964fb08402a07fdd646c3a837493)) ([#710](https://github.com/sapphiredev/plugins/pull/710) by @renovate[bot])
|
|
12
|
+
- **deps:** Update all non-major dependencies ([cc47e19](https://github.com/sapphiredev/plugins/commit/cc47e198df63b90ae64fd9d945ba2d521d17a8f2)) ([#705](https://github.com/sapphiredev/plugins/pull/705) by @renovate[bot])
|
|
13
|
+
- **deps:** Update all non-major dependencies ([fb563e8](https://github.com/sapphiredev/plugins/commit/fb563e8d6b9bc7e3594563ab99838a6abea9032c)) ([#704](https://github.com/sapphiredev/plugins/pull/704) by @renovate[bot])
|
|
14
|
+
- **deps:** Update all non-major dependencies ([689cfd8](https://github.com/sapphiredev/plugins/commit/689cfd8be9e0dccce1aac838e07b77d56e5cc0fa)) ([#695](https://github.com/sapphiredev/plugins/pull/695) by @renovate[bot])
|
|
15
|
+
- **deps:** Update all non-major dependencies ([48a1e26](https://github.com/sapphiredev/plugins/commit/48a1e26ca064fcfe666b6826dacaa2c8bc7714bb)) ([#694](https://github.com/sapphiredev/plugins/pull/694) by @renovate[bot])
|
|
16
|
+
- **deps:** Update all non-major dependencies ([aa2ed66](https://github.com/sapphiredev/plugins/commit/aa2ed66e38e2cae79bd9585149896205c009dd1b)) ([#684](https://github.com/sapphiredev/plugins/pull/684) by @renovate[bot])
|
|
17
|
+
- **deps:** Update all non-major dependencies ([a6eeff6](https://github.com/sapphiredev/plugins/commit/a6eeff668d57c995335e02466eb48fbcb699f3ea))
|
|
18
|
+
- **deps:** Update all non-major dependencies ([c74b327](https://github.com/sapphiredev/plugins/commit/c74b327f7e9beea3d5164f8f5e17fbd8e61f74d7)) ([#678](https://github.com/sapphiredev/plugins/pull/678) by @renovate[bot])
|
|
19
|
+
- **deps:** Update all non-major dependencies ([7c80885](https://github.com/sapphiredev/plugins/commit/7c80885f4798348b0c077d9b87117782f7af67d8)) ([#673](https://github.com/sapphiredev/plugins/pull/673) by @renovate[bot])
|
|
20
|
+
- **deps:** Update all non-major dependencies ([2f82767](https://github.com/sapphiredev/plugins/commit/2f8276724338631c4d6d8c7b553d268d5990cc74)) ([#672](https://github.com/sapphiredev/plugins/pull/672) by @renovate[bot])
|
|
21
|
+
- **deps:** Update dependency i18next to v24 ([f7c0c49](https://github.com/sapphiredev/plugins/commit/f7c0c498cfdddd2970e6a2ef828c97ecf3fdfec4)) ([#664](https://github.com/sapphiredev/plugins/pull/664) by @renovate[bot])
|
|
22
|
+
- 💥 **BREAKING CHANGE:** i18next has been upgraded to v24. Please refer to the i18next migration guide: https://www.i18next.com/misc/migration-guide#v23.x.x-to-v24.0.0. Most importantly you may need to update your JSON files and the Intl API is now mandatory (no problem with NodeJS v18 and above)
|
|
23
|
+
|
|
5
24
|
# [@sapphire/plugin-i18next@7.1.3](https://github.com/sapphiredev/plugins/compare/@sapphire/plugin-i18next@7.1.2...@sapphire/plugin-i18next@7.1.3) - (2024-11-02)
|
|
6
25
|
|
|
7
26
|
## 🏠 Refactor
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -10,7 +10,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
10
|
var i18next__default = /*#__PURE__*/_interopDefault(i18next);
|
|
11
11
|
|
|
12
12
|
// src/index.ts
|
|
13
|
-
var version = "8.0.0
|
|
13
|
+
var version = "8.0.0";
|
|
14
14
|
|
|
15
15
|
Object.defineProperty(exports, "i18next", {
|
|
16
16
|
enumerable: true,
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAyBO,IAAM,OAAkB,GAAA","file":"index.cjs","sourcesContent":["import type { InternationalizationHandler } from './lib/InternationalizationHandler';\nimport type { InternationalizationClientOptions } from './lib/types';\n\nexport { default as i18next, type TFunction, type TOptions } from 'i18next';\nexport * from './lib/InternationalizationHandler';\nexport * from './lib/functions';\nexport * from './lib/types';\n\ndeclare module '@sapphire/pieces' {\n\tinterface Container {\n\t\ti18n: InternationalizationHandler;\n\t}\n}\n\ndeclare module 'discord.js' {\n\texport interface ClientOptions extends InternationalizationClientOptions {}\n}\n\n/**\n * The [@sapphire/plugin-i18next](https://github.com/sapphiredev/plugins/blob/main/packages/i18next) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.0.0
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAyBO,IAAM,OAAkB,GAAA","file":"index.cjs","sourcesContent":["import type { InternationalizationHandler } from './lib/InternationalizationHandler';\nimport type { InternationalizationClientOptions } from './lib/types';\n\nexport { default as i18next, type TFunction, type TOptions } from 'i18next';\nexport * from './lib/InternationalizationHandler';\nexport * from './lib/functions';\nexport * from './lib/types';\n\ndeclare module '@sapphire/pieces' {\n\tinterface Container {\n\t\ti18n: InternationalizationHandler;\n\t}\n}\n\ndeclare module 'discord.js' {\n\texport interface ClientOptions extends InternationalizationClientOptions {}\n}\n\n/**\n * The [@sapphire/plugin-i18next](https://github.com/sapphiredev/plugins/blob/main/packages/i18next) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.0.0';\n"]}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { InitOptions, TFunction, ParseKeys, TOptions, Namespace, DefaultNamespac
|
|
|
5
5
|
export { TFunction, TOptions, default as i18next } from 'i18next';
|
|
6
6
|
import { PathLike } from 'node:fs';
|
|
7
7
|
import { ChokidarOptions } from 'chokidar';
|
|
8
|
-
import { Message, StageChannel, VoiceChannel,
|
|
8
|
+
import { Guild, Message, StageChannel, VoiceChannel, User, Interaction, LocalizationMap, BaseInteraction, APIApplicationCommandOptionChoice } from 'discord.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* This is a re-exported type from i18next.
|
|
@@ -38,7 +38,7 @@ async function resolveKey(target, ...[key, defaultValueOrOptions, optionsOrUndef
|
|
|
38
38
|
if (typeof defaultValueOrOptions === "string") {
|
|
39
39
|
return pieces.container.i18n.format(language, key, defaultValueOrOptions, optionsOrUndefined);
|
|
40
40
|
}
|
|
41
|
-
return pieces.container.i18n.format(language, key,
|
|
41
|
+
return pieces.container.i18n.format(language, key, void 0, defaultValueOrOptions);
|
|
42
42
|
}
|
|
43
43
|
__name(resolveKey, "resolveKey");
|
|
44
44
|
async function resolveLanguage(context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/functions.ts"],"names":["BaseInteraction","Message","Guild","ChannelType","container","Locale","lazy"],"mappings":"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","file":"functions.cjs","sourcesContent":["import { container } from '@sapphire/pieces';\nimport { lazy } from '@sapphire/utilities';\nimport { BaseInteraction, ChannelType, Guild, Locale, Message, type APIApplicationCommandOptionChoice, type LocaleString } from 'discord.js';\nimport type {\n\tAppendKeyPrefix,\n\tDefaultNamespace,\n\tInterpolationMap,\n\tNamespace,\n\tParseKeys,\n\tTFunctionReturn,\n\tTFunctionReturnOptionalDetails,\n\tTOptions\n} from 'i18next';\nimport type {\n\t$Dictionary,\n\t$SpecialObject,\n\tBuilderWithDescription,\n\tBuilderWithName,\n\tBuilderWithNameAndDescription,\n\tInternationalizationContext,\n\tLocalizedData,\n\tTarget\n} from './types';\n\n/**\n * Retrieves the language name for a specific target, using {@link InternationalizationHandler.fetchLanguage}.\n * If {@link InternationalizationHandler.fetchLanguage} is not defined or this function returns a nullish value,\n * then there will be a series of fallback attempts in the following descending order:\n * 1. Returns {@link Guild.preferredLocale}.\n * 2. Returns {@link InternationalizationOptions.defaultName} if no guild was provided.\n * 3. Returns `'en-US'` if nothing else was found.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @see {@link resolveLanguage}\n * @returns The name of the language key.\n */\nexport function fetchLanguage(target: Target): Promise<string> {\n\t// Handle Interactions:\n\tif (target instanceof BaseInteraction) {\n\t\treturn resolveLanguage({\n\t\t\tuser: target.user,\n\t\t\tchannel: target.channel,\n\t\t\tguild: target.guild,\n\t\t\tinteractionGuildLocale: target.guildLocale,\n\t\t\tinteractionLocale: target.locale\n\t\t});\n\t}\n\n\t// Handle Message:\n\tif (target instanceof Message) {\n\t\treturn resolveLanguage({ user: target.author, channel: target.channel, guild: target.guild });\n\t}\n\n\t// Handle Guild:\n\tif (target instanceof Guild) {\n\t\treturn resolveLanguage({ user: null, channel: null, guild: target });\n\t}\n\n\t// Handle DMChannel and GroupDMChannel:\n\tif (target.type === ChannelType.DM || target.type === ChannelType.GroupDM) {\n\t\treturn resolveLanguage({ user: null, channel: target, guild: null });\n\t}\n\n\t// Handle any other channel:\n\treturn resolveLanguage({ user: null, channel: target, guild: target.guild });\n}\n\n/**\n * Retrieves the language-assigned function from i18next designated to a target's preferred language code.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @returns The language function from i18next.\n */\nexport async function fetchT(target: Target) {\n\treturn container.i18n.getT(await fetchLanguage(target));\n}\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The options to be passed to TFunction.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: Key | Key[], options?: ActualOptions): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The interpolation options as well as a `defaultValue` for the key and any key/value pairs.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param defaultValue The default value to use if the key is not found.\n * @param options The interpolation options.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], defaultValue: string, options?: TOpt & $Dictionary): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n *\n * @remark This function also has additional parameters for `key`, `defaultValue`, and `options`, however\n * TSDoc does not let us document those while matching proper implementation. See the overloads for this method\n * for the documentation on those parameters.\n *\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(\n\ttarget: Target,\n\t...[key, defaultValueOrOptions, optionsOrUndefined]:\n\t\t| [key: Key | Key[], options?: ActualOptions]\n\t\t| [key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }]\n\t\t| [key: string | string[], defaultValue: string, options?: TOpt & $Dictionary]\n): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>> {\n\tconst parsedOptions = typeof defaultValueOrOptions === 'string' ? optionsOrUndefined : defaultValueOrOptions;\n\tconst language = typeof parsedOptions?.lng === 'string' ? parsedOptions.lng : await fetchLanguage(target);\n\n\tif (typeof defaultValueOrOptions === 'string') {\n\t\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, defaultValueOrOptions, optionsOrUndefined);\n\t}\n\n\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, undefined, defaultValueOrOptions);\n}\n\n/**\n * @internal\n */\nasync function resolveLanguage(context: InternationalizationContext): Promise<string> {\n\tconst lang = await container.i18n.fetchLanguage(context);\n\treturn lang ?? context.guild?.preferredLocale ?? container.i18n.options.defaultName ?? 'en-US';\n}\n\nconst supportedLanguages = new Set(Object.values(Locale)) as ReadonlySet<LocaleString>;\n\nfunction isSupportedDiscordLocale(language: string): language is LocaleString {\n\treturn supportedLanguages.has(language as LocaleString);\n}\n\nconst getLocales = lazy(() => {\n\tconst locales = new Map(container.i18n.languages);\n\n\tfor (const [locale] of locales) {\n\t\tif (!isSupportedDiscordLocale(locale)) {\n\t\t\tprocess.emitWarning('Unsupported Discord locale', {\n\t\t\t\tcode: 'UNSUPPORTED_LOCALE',\n\t\t\t\tdetail: `'${locale}' needs to be one of: ${[...locales.keys()]}`\n\t\t\t});\n\n\t\t\tlocales.delete(locale);\n\t\t}\n\n\t\tcontinue;\n\t}\n\n\treturn locales;\n});\n\nconst getDefaultT = lazy(() => {\n\tconst defaultLocale = container.i18n.options.defaultName ?? 'en-US';\n\n\tif (!isSupportedDiscordLocale(defaultLocale)) {\n\t\tthrow new TypeError(`Unsupported Discord locale found:\\n'${defaultLocale}' is not within the list of ${[...supportedLanguages]}`);\n\t}\n\n\tconst defaultT = getLocales().get(defaultLocale);\n\n\tif (defaultT) {\n\t\treturn defaultT;\n\t}\n\n\tthrow new TypeError(`Could not find ${defaultLocale}`);\n});\n\n/**\n * Gets the value and the localizations from a language key.\n * @param key The key to get the localizations from.\n * @returns The retrieved data.\n * @remarks This should be called **strictly** after loading the locales.\n */\nexport function getLocalizedData<const TOpt extends TOptions = TOptions, Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>\n): LocalizedData {\n\tconst locales = getLocales();\n\tconst defaultT = getDefaultT();\n\n\treturn {\n\t\tvalue: defaultT(key),\n\t\tlocalizations: Object.fromEntries(Array.from(locales, ([locale, t]) => [locale, t(key)]))\n\t};\n}\n\n/**\n * Applies the localized names on the builder, calling `setName` and `setNameLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyNameLocalizedBuilder<\n\tT extends BuilderWithName,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setName(result.value).setNameLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized descriptions on the builder, calling `setDescription` and `setDescriptionLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyDescriptionLocalizedBuilder<\n\tT extends BuilderWithDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setDescription(result.value).setDescriptionLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized names and descriptions on the builder, calling {@link applyNameLocalizedBuilder} and\n * {@link applyDescriptionLocalizedBuilder}.\n *\n * @param builder The builder to apply the localizations to.\n *\n * @param params The root key or the key for the name and description keys.\n * This needs to be either 1 or 2 parameters.\n * See examples below for more information.\n *\n * @returns The updated builder. You can chain subsequent builder methods on this.\n *\n * @remarks If only 2 parameters were passed, then this function will automatically append `Name` and `Description`\n * to the root-key (wherein `root-key` is second parameter in the function, after `builder`)\n * passed through the second parameter.\n *\n * For example given `applyLocalizedBuilder(builder, 'userinfo')` the localized options will use the i18next keys\n * `userinfoName` and `userinfoDescription`.\n *\n * In the following example we provide all parameters and add a User Option\n * `applyLocalizedBuilder` needs either\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:userinfo', 'commands/descriptions:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'commands/options:userinfo-name', 'commands/options:userinfo-description').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n *\n * In the following example we provide single root keys which means `Name` and `Description` get appended as mentioned above.\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'options:userinfo').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n */\nexport function applyLocalizedBuilder<\n\tT extends BuilderWithNameAndDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, ...params: [root: string] | [name: ParseKeys<Ns, TOpt, KPrefix>, description: ParseKeys<Ns, TOpt, KPrefix>]): T {\n\ttype LocalKeysType = ParseKeys<Ns, TOpt, KPrefix>;\n\n\tconst [localeName, localeDescription] =\n\t\tparams.length === 1 ? [`${params[0]}Name` as LocalKeysType, `${params[0]}Description` as LocalKeysType] : params;\n\n\tapplyNameLocalizedBuilder(builder, localeName);\n\tapplyDescriptionLocalizedBuilder(builder, localeDescription);\n\n\treturn builder;\n}\n\n/**\n * Constructs an object that can be passed into `setChoices` for String or Number option with localized names.\n *\n * @param key The i18next key for the name of the select option name.\n * @param options The additional Select Menu options. This should _at least_ include the `value` key.\n * @returns An object with anything provided through {@link createLocalizedChoice.options} with `name` and `name_localizations` added.\n *\n * @example\n * ```typescript\n * export class TypeCommand extends Command {\n * public override registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand((builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:type').addStringOption((option) =>\n * applyLocalizedBuilder(option, 'commands/options:type')\n * .setRequired(true)\n * .setChoices(\n * createLocalizedChoice('selects/pokemon:type-grass', { value: 'grass' }),\n * createLocalizedChoice('selects/pokemon:type-water', { value: 'water' }),\n * createLocalizedChoice('selects/pokemon:type-fire', { value: 'fire' }),\n * createLocalizedChoice('selects/pokemon:type-electric', { value: 'electric' })\n * )\n * )\n * );\n * }\n * }\n * ```\n */\nexport function createLocalizedChoice<\n\tValueType = string | number,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>,\n\toptions: Omit<APIApplicationCommandOptionChoice<ValueType>, 'name' | 'name_localizations'>\n): APIApplicationCommandOptionChoice<ValueType> {\n\tconst result = getLocalizedData(key);\n\n\treturn {\n\t\t...options,\n\t\tname: result.value,\n\t\tname_localizations: result.localizations\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/functions.ts"],"names":["BaseInteraction","Message","Guild","ChannelType","container","Locale","lazy"],"mappings":"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","file":"functions.cjs","sourcesContent":["import { container } from '@sapphire/pieces';\nimport { lazy } from '@sapphire/utilities';\nimport { BaseInteraction, ChannelType, Guild, Locale, Message, type APIApplicationCommandOptionChoice, type LocaleString } from 'discord.js';\nimport type {\n\tAppendKeyPrefix,\n\tDefaultNamespace,\n\tInterpolationMap,\n\tNamespace,\n\tParseKeys,\n\tTFunctionReturn,\n\tTFunctionReturnOptionalDetails,\n\tTOptions\n} from 'i18next';\nimport type {\n\t$Dictionary,\n\t$SpecialObject,\n\tBuilderWithDescription,\n\tBuilderWithName,\n\tBuilderWithNameAndDescription,\n\tInternationalizationContext,\n\tLocalizedData,\n\tTarget\n} from './types';\n\n/**\n * Retrieves the language name for a specific target, using {@link InternationalizationHandler.fetchLanguage}.\n * If {@link InternationalizationHandler.fetchLanguage} is not defined or this function returns a nullish value,\n * then there will be a series of fallback attempts in the following descending order:\n * 1. Returns {@link Guild.preferredLocale}.\n * 2. Returns {@link InternationalizationOptions.defaultName} if no guild was provided.\n * 3. Returns `'en-US'` if nothing else was found.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @see {@link resolveLanguage}\n * @returns The name of the language key.\n */\nexport function fetchLanguage(target: Target): Promise<string> {\n\t// Handle Interactions:\n\tif (target instanceof BaseInteraction) {\n\t\treturn resolveLanguage({\n\t\t\tuser: target.user,\n\t\t\tchannel: target.channel,\n\t\t\tguild: target.guild,\n\t\t\tinteractionGuildLocale: target.guildLocale,\n\t\t\tinteractionLocale: target.locale\n\t\t});\n\t}\n\n\t// Handle Message:\n\tif (target instanceof Message) {\n\t\treturn resolveLanguage({ user: target.author, channel: target.channel, guild: target.guild });\n\t}\n\n\t// Handle Guild:\n\tif (target instanceof Guild) {\n\t\treturn resolveLanguage({ user: null, channel: null, guild: target });\n\t}\n\n\t// Handle DMChannel and GroupDMChannel:\n\tif (target.type === ChannelType.DM || target.type === ChannelType.GroupDM) {\n\t\treturn resolveLanguage({ user: null, channel: target, guild: null });\n\t}\n\n\t// Handle any other channel:\n\treturn resolveLanguage({ user: null, channel: target, guild: target.guild });\n}\n\n/**\n * Retrieves the language-assigned function from i18next designated to a target's preferred language code.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @returns The language function from i18next.\n */\nexport async function fetchT(target: Target) {\n\treturn container.i18n.getT(await fetchLanguage(target));\n}\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The options to be passed to TFunction.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: Key | Key[], options?: ActualOptions): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The interpolation options as well as a `defaultValue` for the key and any key/value pairs.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param defaultValue The default value to use if the key is not found.\n * @param options The interpolation options.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], defaultValue: string, options?: TOpt & $Dictionary): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n *\n * @remark This function also has additional parameters for `key`, `defaultValue`, and `options`, however\n * TSDoc does not let us document those while matching proper implementation. See the overloads for this method\n * for the documentation on those parameters.\n *\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(\n\ttarget: Target,\n\t...[key, defaultValueOrOptions, optionsOrUndefined]:\n\t\t| [key: Key | Key[], options?: ActualOptions]\n\t\t| [key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }]\n\t\t| [key: string | string[], defaultValue: string, options?: TOpt & $Dictionary]\n): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>> {\n\tconst parsedOptions = typeof defaultValueOrOptions === 'string' ? optionsOrUndefined : defaultValueOrOptions;\n\tconst language = typeof parsedOptions?.lng === 'string' ? parsedOptions.lng : await fetchLanguage(target);\n\n\tif (typeof defaultValueOrOptions === 'string') {\n\t\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, defaultValueOrOptions, optionsOrUndefined);\n\t}\n\n\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, undefined, defaultValueOrOptions);\n}\n\n/**\n * @internal\n */\nasync function resolveLanguage(context: InternationalizationContext): Promise<string> {\n\tconst lang = await container.i18n.fetchLanguage(context);\n\treturn lang ?? context.guild?.preferredLocale ?? container.i18n.options.defaultName ?? 'en-US';\n}\n\nconst supportedLanguages = new Set(Object.values(Locale)) as ReadonlySet<LocaleString>;\n\nfunction isSupportedDiscordLocale(language: string): language is LocaleString {\n\treturn supportedLanguages.has(language as LocaleString);\n}\n\nconst getLocales = lazy(() => {\n\tconst locales = new Map(container.i18n.languages);\n\n\tfor (const [locale] of locales) {\n\t\tif (!isSupportedDiscordLocale(locale)) {\n\t\t\tprocess.emitWarning('Unsupported Discord locale', {\n\t\t\t\tcode: 'UNSUPPORTED_LOCALE',\n\t\t\t\tdetail: `'${locale}' needs to be one of: ${[...locales.keys()]}`\n\t\t\t});\n\n\t\t\tlocales.delete(locale);\n\t\t}\n\n\t\tcontinue;\n\t}\n\n\treturn locales;\n});\n\nconst getDefaultT = lazy(() => {\n\tconst defaultLocale = container.i18n.options.defaultName ?? 'en-US';\n\n\tif (!isSupportedDiscordLocale(defaultLocale)) {\n\t\tthrow new TypeError(`Unsupported Discord locale found:\\n'${defaultLocale}' is not within the list of ${[...supportedLanguages]}`);\n\t}\n\n\tconst defaultT = getLocales().get(defaultLocale);\n\n\tif (defaultT) {\n\t\treturn defaultT;\n\t}\n\n\tthrow new TypeError(`Could not find ${defaultLocale}`);\n});\n\n/**\n * Gets the value and the localizations from a language key.\n * @param key The key to get the localizations from.\n * @returns The retrieved data.\n * @remarks This should be called **strictly** after loading the locales.\n */\nexport function getLocalizedData<const TOpt extends TOptions = TOptions, Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>\n): LocalizedData {\n\tconst locales = getLocales();\n\tconst defaultT = getDefaultT();\n\n\treturn {\n\t\tvalue: defaultT(key),\n\t\tlocalizations: Object.fromEntries(Array.from(locales, ([locale, t]) => [locale, t(key)]))\n\t};\n}\n\n/**\n * Applies the localized names on the builder, calling `setName` and `setNameLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyNameLocalizedBuilder<\n\tT extends BuilderWithName,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setName(result.value).setNameLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized descriptions on the builder, calling `setDescription` and `setDescriptionLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyDescriptionLocalizedBuilder<\n\tT extends BuilderWithDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setDescription(result.value).setDescriptionLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized names and descriptions on the builder, calling {@link applyNameLocalizedBuilder} and\n * {@link applyDescriptionLocalizedBuilder}.\n *\n * @param builder The builder to apply the localizations to.\n *\n * @param params The root key or the key for the name and description keys.\n * This needs to be either 1 or 2 parameters.\n * See examples below for more information.\n *\n * @returns The updated builder. You can chain subsequent builder methods on this.\n *\n * @remarks If only 2 parameters were passed, then this function will automatically append `Name` and `Description`\n * to the root-key (wherein `root-key` is second parameter in the function, after `builder`)\n * passed through the second parameter.\n *\n * For example given `applyLocalizedBuilder(builder, 'userinfo')` the localized options will use the i18next keys\n * `userinfoName` and `userinfoDescription`.\n *\n * In the following example we provide all parameters and add a User Option\n * `applyLocalizedBuilder` needs either\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:userinfo', 'commands/descriptions:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'commands/options:userinfo-name', 'commands/options:userinfo-description').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n *\n * In the following example we provide single root keys which means `Name` and `Description` get appended as mentioned above.\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'options:userinfo').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n */\nexport function applyLocalizedBuilder<\n\tT extends BuilderWithNameAndDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, ...params: [root: string] | [name: ParseKeys<Ns, TOpt, KPrefix>, description: ParseKeys<Ns, TOpt, KPrefix>]): T {\n\ttype LocalKeysType = ParseKeys<Ns, TOpt, KPrefix>;\n\n\tconst [localeName, localeDescription] =\n\t\tparams.length === 1 ? [`${params[0]}Name` as LocalKeysType, `${params[0]}Description` as LocalKeysType] : params;\n\n\tapplyNameLocalizedBuilder(builder, localeName);\n\tapplyDescriptionLocalizedBuilder(builder, localeDescription);\n\n\treturn builder;\n}\n\n/**\n * Constructs an object that can be passed into `setChoices` for String or Number option with localized names.\n *\n * @param key The i18next key for the name of the select option name.\n * @param options The additional Select Menu options. This should _at least_ include the `value` key.\n * @returns An object with anything provided through {@link createLocalizedChoice.options} with `name` and `name_localizations` added.\n *\n * @example\n * ```typescript\n * export class TypeCommand extends Command {\n * public override registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand((builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:type').addStringOption((option) =>\n * applyLocalizedBuilder(option, 'commands/options:type')\n * .setRequired(true)\n * .setChoices(\n * createLocalizedChoice('selects/pokemon:type-grass', { value: 'grass' }),\n * createLocalizedChoice('selects/pokemon:type-water', { value: 'water' }),\n * createLocalizedChoice('selects/pokemon:type-fire', { value: 'fire' }),\n * createLocalizedChoice('selects/pokemon:type-electric', { value: 'electric' })\n * )\n * )\n * );\n * }\n * }\n * ```\n */\nexport function createLocalizedChoice<\n\tValueType = string | number,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>,\n\toptions: Omit<APIApplicationCommandOptionChoice<ValueType>, 'name' | 'name_localizations'>\n): APIApplicationCommandOptionChoice<ValueType> {\n\tconst result = getLocalizedData(key);\n\n\treturn {\n\t\t...options,\n\t\tname: result.value,\n\t\tname_localizations: result.localizations\n\t};\n}\n"]}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { InitOptions, TFunction, ParseKeys, TOptions, Namespace, DefaultNamespac
|
|
|
5
5
|
export { TFunction, TOptions, default as i18next } from 'i18next';
|
|
6
6
|
import { PathLike } from 'node:fs';
|
|
7
7
|
import { ChokidarOptions } from 'chokidar';
|
|
8
|
-
import { Message, StageChannel, VoiceChannel,
|
|
8
|
+
import { Guild, Message, StageChannel, VoiceChannel, User, Interaction, LocalizationMap, BaseInteraction, APIApplicationCommandOptionChoice } from 'discord.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* This is a re-exported type from i18next.
|
package/dist/esm/index.mjs
CHANGED
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;AAyBO,IAAM,OAAkB,GAAA","file":"index.mjs","sourcesContent":["import type { InternationalizationHandler } from './lib/InternationalizationHandler';\nimport type { InternationalizationClientOptions } from './lib/types';\n\nexport { default as i18next, type TFunction, type TOptions } from 'i18next';\nexport * from './lib/InternationalizationHandler';\nexport * from './lib/functions';\nexport * from './lib/types';\n\ndeclare module '@sapphire/pieces' {\n\tinterface Container {\n\t\ti18n: InternationalizationHandler;\n\t}\n}\n\ndeclare module 'discord.js' {\n\texport interface ClientOptions extends InternationalizationClientOptions {}\n}\n\n/**\n * The [@sapphire/plugin-i18next](https://github.com/sapphiredev/plugins/blob/main/packages/i18next) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.0.0
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;AAyBO,IAAM,OAAkB,GAAA","file":"index.mjs","sourcesContent":["import type { InternationalizationHandler } from './lib/InternationalizationHandler';\nimport type { InternationalizationClientOptions } from './lib/types';\n\nexport { default as i18next, type TFunction, type TOptions } from 'i18next';\nexport * from './lib/InternationalizationHandler';\nexport * from './lib/functions';\nexport * from './lib/types';\n\ndeclare module '@sapphire/pieces' {\n\tinterface Container {\n\t\ti18n: InternationalizationHandler;\n\t}\n}\n\ndeclare module 'discord.js' {\n\texport interface ClientOptions extends InternationalizationClientOptions {}\n}\n\n/**\n * The [@sapphire/plugin-i18next](https://github.com/sapphiredev/plugins/blob/main/packages/i18next) version that you are currently using.\n * An example use of this is showing it of in a bot information command.\n *\n * Note to Sapphire developers: This needs to explicitly be `string` so it is not typed as the string that gets replaced by esbuild\n */\n// eslint-disable-next-line @typescript-eslint/no-inferrable-types\nexport const version: string = '8.0.0';\n"]}
|
|
@@ -35,7 +35,7 @@ async function resolveKey(target, ...[key, defaultValueOrOptions, optionsOrUndef
|
|
|
35
35
|
if (typeof defaultValueOrOptions === "string") {
|
|
36
36
|
return container.i18n.format(language, key, defaultValueOrOptions, optionsOrUndefined);
|
|
37
37
|
}
|
|
38
|
-
return container.i18n.format(language, key,
|
|
38
|
+
return container.i18n.format(language, key, void 0, defaultValueOrOptions);
|
|
39
39
|
}
|
|
40
40
|
__name(resolveKey, "resolveKey");
|
|
41
41
|
async function resolveLanguage(context) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/functions.ts"],"names":[],"mappings":"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","file":"functions.mjs","sourcesContent":["import { container } from '@sapphire/pieces';\nimport { lazy } from '@sapphire/utilities';\nimport { BaseInteraction, ChannelType, Guild, Locale, Message, type APIApplicationCommandOptionChoice, type LocaleString } from 'discord.js';\nimport type {\n\tAppendKeyPrefix,\n\tDefaultNamespace,\n\tInterpolationMap,\n\tNamespace,\n\tParseKeys,\n\tTFunctionReturn,\n\tTFunctionReturnOptionalDetails,\n\tTOptions\n} from 'i18next';\nimport type {\n\t$Dictionary,\n\t$SpecialObject,\n\tBuilderWithDescription,\n\tBuilderWithName,\n\tBuilderWithNameAndDescription,\n\tInternationalizationContext,\n\tLocalizedData,\n\tTarget\n} from './types';\n\n/**\n * Retrieves the language name for a specific target, using {@link InternationalizationHandler.fetchLanguage}.\n * If {@link InternationalizationHandler.fetchLanguage} is not defined or this function returns a nullish value,\n * then there will be a series of fallback attempts in the following descending order:\n * 1. Returns {@link Guild.preferredLocale}.\n * 2. Returns {@link InternationalizationOptions.defaultName} if no guild was provided.\n * 3. Returns `'en-US'` if nothing else was found.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @see {@link resolveLanguage}\n * @returns The name of the language key.\n */\nexport function fetchLanguage(target: Target): Promise<string> {\n\t// Handle Interactions:\n\tif (target instanceof BaseInteraction) {\n\t\treturn resolveLanguage({\n\t\t\tuser: target.user,\n\t\t\tchannel: target.channel,\n\t\t\tguild: target.guild,\n\t\t\tinteractionGuildLocale: target.guildLocale,\n\t\t\tinteractionLocale: target.locale\n\t\t});\n\t}\n\n\t// Handle Message:\n\tif (target instanceof Message) {\n\t\treturn resolveLanguage({ user: target.author, channel: target.channel, guild: target.guild });\n\t}\n\n\t// Handle Guild:\n\tif (target instanceof Guild) {\n\t\treturn resolveLanguage({ user: null, channel: null, guild: target });\n\t}\n\n\t// Handle DMChannel and GroupDMChannel:\n\tif (target.type === ChannelType.DM || target.type === ChannelType.GroupDM) {\n\t\treturn resolveLanguage({ user: null, channel: target, guild: null });\n\t}\n\n\t// Handle any other channel:\n\treturn resolveLanguage({ user: null, channel: target, guild: target.guild });\n}\n\n/**\n * Retrieves the language-assigned function from i18next designated to a target's preferred language code.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @returns The language function from i18next.\n */\nexport async function fetchT(target: Target) {\n\treturn container.i18n.getT(await fetchLanguage(target));\n}\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The options to be passed to TFunction.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: Key | Key[], options?: ActualOptions): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The interpolation options as well as a `defaultValue` for the key and any key/value pairs.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param defaultValue The default value to use if the key is not found.\n * @param options The interpolation options.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], defaultValue: string, options?: TOpt & $Dictionary): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n *\n * @remark This function also has additional parameters for `key`, `defaultValue`, and `options`, however\n * TSDoc does not let us document those while matching proper implementation. See the overloads for this method\n * for the documentation on those parameters.\n *\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(\n\ttarget: Target,\n\t...[key, defaultValueOrOptions, optionsOrUndefined]:\n\t\t| [key: Key | Key[], options?: ActualOptions]\n\t\t| [key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }]\n\t\t| [key: string | string[], defaultValue: string, options?: TOpt & $Dictionary]\n): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>> {\n\tconst parsedOptions = typeof defaultValueOrOptions === 'string' ? optionsOrUndefined : defaultValueOrOptions;\n\tconst language = typeof parsedOptions?.lng === 'string' ? parsedOptions.lng : await fetchLanguage(target);\n\n\tif (typeof defaultValueOrOptions === 'string') {\n\t\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, defaultValueOrOptions, optionsOrUndefined);\n\t}\n\n\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, undefined, defaultValueOrOptions);\n}\n\n/**\n * @internal\n */\nasync function resolveLanguage(context: InternationalizationContext): Promise<string> {\n\tconst lang = await container.i18n.fetchLanguage(context);\n\treturn lang ?? context.guild?.preferredLocale ?? container.i18n.options.defaultName ?? 'en-US';\n}\n\nconst supportedLanguages = new Set(Object.values(Locale)) as ReadonlySet<LocaleString>;\n\nfunction isSupportedDiscordLocale(language: string): language is LocaleString {\n\treturn supportedLanguages.has(language as LocaleString);\n}\n\nconst getLocales = lazy(() => {\n\tconst locales = new Map(container.i18n.languages);\n\n\tfor (const [locale] of locales) {\n\t\tif (!isSupportedDiscordLocale(locale)) {\n\t\t\tprocess.emitWarning('Unsupported Discord locale', {\n\t\t\t\tcode: 'UNSUPPORTED_LOCALE',\n\t\t\t\tdetail: `'${locale}' needs to be one of: ${[...locales.keys()]}`\n\t\t\t});\n\n\t\t\tlocales.delete(locale);\n\t\t}\n\n\t\tcontinue;\n\t}\n\n\treturn locales;\n});\n\nconst getDefaultT = lazy(() => {\n\tconst defaultLocale = container.i18n.options.defaultName ?? 'en-US';\n\n\tif (!isSupportedDiscordLocale(defaultLocale)) {\n\t\tthrow new TypeError(`Unsupported Discord locale found:\\n'${defaultLocale}' is not within the list of ${[...supportedLanguages]}`);\n\t}\n\n\tconst defaultT = getLocales().get(defaultLocale);\n\n\tif (defaultT) {\n\t\treturn defaultT;\n\t}\n\n\tthrow new TypeError(`Could not find ${defaultLocale}`);\n});\n\n/**\n * Gets the value and the localizations from a language key.\n * @param key The key to get the localizations from.\n * @returns The retrieved data.\n * @remarks This should be called **strictly** after loading the locales.\n */\nexport function getLocalizedData<const TOpt extends TOptions = TOptions, Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>\n): LocalizedData {\n\tconst locales = getLocales();\n\tconst defaultT = getDefaultT();\n\n\treturn {\n\t\tvalue: defaultT(key),\n\t\tlocalizations: Object.fromEntries(Array.from(locales, ([locale, t]) => [locale, t(key)]))\n\t};\n}\n\n/**\n * Applies the localized names on the builder, calling `setName` and `setNameLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyNameLocalizedBuilder<\n\tT extends BuilderWithName,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setName(result.value).setNameLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized descriptions on the builder, calling `setDescription` and `setDescriptionLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyDescriptionLocalizedBuilder<\n\tT extends BuilderWithDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setDescription(result.value).setDescriptionLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized names and descriptions on the builder, calling {@link applyNameLocalizedBuilder} and\n * {@link applyDescriptionLocalizedBuilder}.\n *\n * @param builder The builder to apply the localizations to.\n *\n * @param params The root key or the key for the name and description keys.\n * This needs to be either 1 or 2 parameters.\n * See examples below for more information.\n *\n * @returns The updated builder. You can chain subsequent builder methods on this.\n *\n * @remarks If only 2 parameters were passed, then this function will automatically append `Name` and `Description`\n * to the root-key (wherein `root-key` is second parameter in the function, after `builder`)\n * passed through the second parameter.\n *\n * For example given `applyLocalizedBuilder(builder, 'userinfo')` the localized options will use the i18next keys\n * `userinfoName` and `userinfoDescription`.\n *\n * In the following example we provide all parameters and add a User Option\n * `applyLocalizedBuilder` needs either\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:userinfo', 'commands/descriptions:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'commands/options:userinfo-name', 'commands/options:userinfo-description').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n *\n * In the following example we provide single root keys which means `Name` and `Description` get appended as mentioned above.\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'options:userinfo').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n */\nexport function applyLocalizedBuilder<\n\tT extends BuilderWithNameAndDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, ...params: [root: string] | [name: ParseKeys<Ns, TOpt, KPrefix>, description: ParseKeys<Ns, TOpt, KPrefix>]): T {\n\ttype LocalKeysType = ParseKeys<Ns, TOpt, KPrefix>;\n\n\tconst [localeName, localeDescription] =\n\t\tparams.length === 1 ? [`${params[0]}Name` as LocalKeysType, `${params[0]}Description` as LocalKeysType] : params;\n\n\tapplyNameLocalizedBuilder(builder, localeName);\n\tapplyDescriptionLocalizedBuilder(builder, localeDescription);\n\n\treturn builder;\n}\n\n/**\n * Constructs an object that can be passed into `setChoices` for String or Number option with localized names.\n *\n * @param key The i18next key for the name of the select option name.\n * @param options The additional Select Menu options. This should _at least_ include the `value` key.\n * @returns An object with anything provided through {@link createLocalizedChoice.options} with `name` and `name_localizations` added.\n *\n * @example\n * ```typescript\n * export class TypeCommand extends Command {\n * public override registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand((builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:type').addStringOption((option) =>\n * applyLocalizedBuilder(option, 'commands/options:type')\n * .setRequired(true)\n * .setChoices(\n * createLocalizedChoice('selects/pokemon:type-grass', { value: 'grass' }),\n * createLocalizedChoice('selects/pokemon:type-water', { value: 'water' }),\n * createLocalizedChoice('selects/pokemon:type-fire', { value: 'fire' }),\n * createLocalizedChoice('selects/pokemon:type-electric', { value: 'electric' })\n * )\n * )\n * );\n * }\n * }\n * ```\n */\nexport function createLocalizedChoice<\n\tValueType = string | number,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>,\n\toptions: Omit<APIApplicationCommandOptionChoice<ValueType>, 'name' | 'name_localizations'>\n): APIApplicationCommandOptionChoice<ValueType> {\n\tconst result = getLocalizedData(key);\n\n\treturn {\n\t\t...options,\n\t\tname: result.value,\n\t\tname_localizations: result.localizations\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/functions.ts"],"names":[],"mappings":"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","file":"functions.mjs","sourcesContent":["import { container } from '@sapphire/pieces';\nimport { lazy } from '@sapphire/utilities';\nimport { BaseInteraction, ChannelType, Guild, Locale, Message, type APIApplicationCommandOptionChoice, type LocaleString } from 'discord.js';\nimport type {\n\tAppendKeyPrefix,\n\tDefaultNamespace,\n\tInterpolationMap,\n\tNamespace,\n\tParseKeys,\n\tTFunctionReturn,\n\tTFunctionReturnOptionalDetails,\n\tTOptions\n} from 'i18next';\nimport type {\n\t$Dictionary,\n\t$SpecialObject,\n\tBuilderWithDescription,\n\tBuilderWithName,\n\tBuilderWithNameAndDescription,\n\tInternationalizationContext,\n\tLocalizedData,\n\tTarget\n} from './types';\n\n/**\n * Retrieves the language name for a specific target, using {@link InternationalizationHandler.fetchLanguage}.\n * If {@link InternationalizationHandler.fetchLanguage} is not defined or this function returns a nullish value,\n * then there will be a series of fallback attempts in the following descending order:\n * 1. Returns {@link Guild.preferredLocale}.\n * 2. Returns {@link InternationalizationOptions.defaultName} if no guild was provided.\n * 3. Returns `'en-US'` if nothing else was found.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @see {@link resolveLanguage}\n * @returns The name of the language key.\n */\nexport function fetchLanguage(target: Target): Promise<string> {\n\t// Handle Interactions:\n\tif (target instanceof BaseInteraction) {\n\t\treturn resolveLanguage({\n\t\t\tuser: target.user,\n\t\t\tchannel: target.channel,\n\t\t\tguild: target.guild,\n\t\t\tinteractionGuildLocale: target.guildLocale,\n\t\t\tinteractionLocale: target.locale\n\t\t});\n\t}\n\n\t// Handle Message:\n\tif (target instanceof Message) {\n\t\treturn resolveLanguage({ user: target.author, channel: target.channel, guild: target.guild });\n\t}\n\n\t// Handle Guild:\n\tif (target instanceof Guild) {\n\t\treturn resolveLanguage({ user: null, channel: null, guild: target });\n\t}\n\n\t// Handle DMChannel and GroupDMChannel:\n\tif (target.type === ChannelType.DM || target.type === ChannelType.GroupDM) {\n\t\treturn resolveLanguage({ user: null, channel: target, guild: null });\n\t}\n\n\t// Handle any other channel:\n\treturn resolveLanguage({ user: null, channel: target, guild: target.guild });\n}\n\n/**\n * Retrieves the language-assigned function from i18next designated to a target's preferred language code.\n * @since 2.0.0\n * @param target The target to fetch the language from.\n * @returns The language function from i18next.\n */\nexport async function fetchT(target: Target) {\n\treturn container.i18n.getT(await fetchLanguage(target));\n}\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The options to be passed to TFunction.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: Key | Key[], options?: ActualOptions): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param options The interpolation options as well as a `defaultValue` for the key and any key/value pairs.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n * @param key The i18next key.\n * @param defaultValue The default value to use if the key is not found.\n * @param options The interpolation options.\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(target: Target, key: string | string[], defaultValue: string, options?: TOpt & $Dictionary): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>>;\n\n/**\n * Resolves a key and its parameters.\n * @since 2.0.0\n * @param target The target to fetch the language key from.\n *\n * @remark This function also has additional parameters for `key`, `defaultValue`, and `options`, however\n * TSDoc does not let us document those while matching proper implementation. See the overloads for this method\n * for the documentation on those parameters.\n *\n * @returns The data that `key` held, processed by i18next.\n */\nexport async function resolveKey<\n\tconst Key extends ParseKeys<Ns, TOpt, undefined>,\n\tconst TOpt extends TOptions = TOptions,\n\tRet extends TFunctionReturn<Ns, AppendKeyPrefix<Key, undefined>, TOpt> = TOpt['returnObjects'] extends true ? $SpecialObject : string,\n\tNs extends Namespace = DefaultNamespace,\n\tconst ActualOptions extends TOpt & InterpolationMap<Ret> = TOpt & InterpolationMap<Ret>\n>(\n\ttarget: Target,\n\t...[key, defaultValueOrOptions, optionsOrUndefined]:\n\t\t| [key: Key | Key[], options?: ActualOptions]\n\t\t| [key: string | string[], options: TOpt & $Dictionary & { defaultValue: string }]\n\t\t| [key: string | string[], defaultValue: string, options?: TOpt & $Dictionary]\n): Promise<TFunctionReturnOptionalDetails<Ret, TOpt>> {\n\tconst parsedOptions = typeof defaultValueOrOptions === 'string' ? optionsOrUndefined : defaultValueOrOptions;\n\tconst language = typeof parsedOptions?.lng === 'string' ? parsedOptions.lng : await fetchLanguage(target);\n\n\tif (typeof defaultValueOrOptions === 'string') {\n\t\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, defaultValueOrOptions, optionsOrUndefined);\n\t}\n\n\treturn container.i18n.format<Key, TOpt, Ns, Ret, ActualOptions>(language, key, undefined, defaultValueOrOptions);\n}\n\n/**\n * @internal\n */\nasync function resolveLanguage(context: InternationalizationContext): Promise<string> {\n\tconst lang = await container.i18n.fetchLanguage(context);\n\treturn lang ?? context.guild?.preferredLocale ?? container.i18n.options.defaultName ?? 'en-US';\n}\n\nconst supportedLanguages = new Set(Object.values(Locale)) as ReadonlySet<LocaleString>;\n\nfunction isSupportedDiscordLocale(language: string): language is LocaleString {\n\treturn supportedLanguages.has(language as LocaleString);\n}\n\nconst getLocales = lazy(() => {\n\tconst locales = new Map(container.i18n.languages);\n\n\tfor (const [locale] of locales) {\n\t\tif (!isSupportedDiscordLocale(locale)) {\n\t\t\tprocess.emitWarning('Unsupported Discord locale', {\n\t\t\t\tcode: 'UNSUPPORTED_LOCALE',\n\t\t\t\tdetail: `'${locale}' needs to be one of: ${[...locales.keys()]}`\n\t\t\t});\n\n\t\t\tlocales.delete(locale);\n\t\t}\n\n\t\tcontinue;\n\t}\n\n\treturn locales;\n});\n\nconst getDefaultT = lazy(() => {\n\tconst defaultLocale = container.i18n.options.defaultName ?? 'en-US';\n\n\tif (!isSupportedDiscordLocale(defaultLocale)) {\n\t\tthrow new TypeError(`Unsupported Discord locale found:\\n'${defaultLocale}' is not within the list of ${[...supportedLanguages]}`);\n\t}\n\n\tconst defaultT = getLocales().get(defaultLocale);\n\n\tif (defaultT) {\n\t\treturn defaultT;\n\t}\n\n\tthrow new TypeError(`Could not find ${defaultLocale}`);\n});\n\n/**\n * Gets the value and the localizations from a language key.\n * @param key The key to get the localizations from.\n * @returns The retrieved data.\n * @remarks This should be called **strictly** after loading the locales.\n */\nexport function getLocalizedData<const TOpt extends TOptions = TOptions, Ns extends Namespace = DefaultNamespace, KPrefix = undefined>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>\n): LocalizedData {\n\tconst locales = getLocales();\n\tconst defaultT = getDefaultT();\n\n\treturn {\n\t\tvalue: defaultT(key),\n\t\tlocalizations: Object.fromEntries(Array.from(locales, ([locale, t]) => [locale, t(key)]))\n\t};\n}\n\n/**\n * Applies the localized names on the builder, calling `setName` and `setNameLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyNameLocalizedBuilder<\n\tT extends BuilderWithName,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setName(result.value).setNameLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized descriptions on the builder, calling `setDescription` and `setDescriptionLocalizations`.\n * @param builder The builder to apply the localizations to.\n * @param key The key to get the localizations from.\n * @returns The updated builder.\n */\nexport function applyDescriptionLocalizedBuilder<\n\tT extends BuilderWithDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, key: ParseKeys<Ns, TOpt, KPrefix>) {\n\tconst result = getLocalizedData(key);\n\treturn builder.setDescription(result.value).setDescriptionLocalizations(result.localizations);\n}\n\n/**\n * Applies the localized names and descriptions on the builder, calling {@link applyNameLocalizedBuilder} and\n * {@link applyDescriptionLocalizedBuilder}.\n *\n * @param builder The builder to apply the localizations to.\n *\n * @param params The root key or the key for the name and description keys.\n * This needs to be either 1 or 2 parameters.\n * See examples below for more information.\n *\n * @returns The updated builder. You can chain subsequent builder methods on this.\n *\n * @remarks If only 2 parameters were passed, then this function will automatically append `Name` and `Description`\n * to the root-key (wherein `root-key` is second parameter in the function, after `builder`)\n * passed through the second parameter.\n *\n * For example given `applyLocalizedBuilder(builder, 'userinfo')` the localized options will use the i18next keys\n * `userinfoName` and `userinfoDescription`.\n *\n * In the following example we provide all parameters and add a User Option\n * `applyLocalizedBuilder` needs either\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:userinfo', 'commands/descriptions:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'commands/options:userinfo-name', 'commands/options:userinfo-description').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n *\n * In the following example we provide single root keys which means `Name` and `Description` get appended as mentioned above.\n * @example\n * ```typescript\n * class UserInfoCommand extends Command {\n * public registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand(\n * (builder) =>\n * applyLocalizedBuilder(builder, 'commands:userinfo')\n * .addUserOption(\n * (input) => applyLocalizedBuilder(input, 'options:userinfo').setRequired(true)\n * )\n * );\n * }\n * }\n * ```\n */\nexport function applyLocalizedBuilder<\n\tT extends BuilderWithNameAndDescription,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(builder: T, ...params: [root: string] | [name: ParseKeys<Ns, TOpt, KPrefix>, description: ParseKeys<Ns, TOpt, KPrefix>]): T {\n\ttype LocalKeysType = ParseKeys<Ns, TOpt, KPrefix>;\n\n\tconst [localeName, localeDescription] =\n\t\tparams.length === 1 ? [`${params[0]}Name` as LocalKeysType, `${params[0]}Description` as LocalKeysType] : params;\n\n\tapplyNameLocalizedBuilder(builder, localeName);\n\tapplyDescriptionLocalizedBuilder(builder, localeDescription);\n\n\treturn builder;\n}\n\n/**\n * Constructs an object that can be passed into `setChoices` for String or Number option with localized names.\n *\n * @param key The i18next key for the name of the select option name.\n * @param options The additional Select Menu options. This should _at least_ include the `value` key.\n * @returns An object with anything provided through {@link createLocalizedChoice.options} with `name` and `name_localizations` added.\n *\n * @example\n * ```typescript\n * export class TypeCommand extends Command {\n * public override registerApplicationCommands(registry: ChatInputCommand.Registry) {\n * registry.registerChatInputCommand((builder) =>\n * applyLocalizedBuilder(builder, 'commands/names:type').addStringOption((option) =>\n * applyLocalizedBuilder(option, 'commands/options:type')\n * .setRequired(true)\n * .setChoices(\n * createLocalizedChoice('selects/pokemon:type-grass', { value: 'grass' }),\n * createLocalizedChoice('selects/pokemon:type-water', { value: 'water' }),\n * createLocalizedChoice('selects/pokemon:type-fire', { value: 'fire' }),\n * createLocalizedChoice('selects/pokemon:type-electric', { value: 'electric' })\n * )\n * )\n * );\n * }\n * }\n * ```\n */\nexport function createLocalizedChoice<\n\tValueType = string | number,\n\tconst TOpt extends TOptions = TOptions,\n\tNs extends Namespace = DefaultNamespace,\n\tKPrefix = undefined\n>(\n\tkey: ParseKeys<Ns, TOpt, KPrefix>,\n\toptions: Omit<APIApplicationCommandOptionChoice<ValueType>, 'name' | 'name_localizations'>\n): APIApplicationCommandOptionChoice<ValueType> {\n\tconst result = getLocalizedData(key);\n\n\treturn {\n\t\t...options,\n\t\tname: result.value,\n\t\tname_localizations: result.localizations\n\t};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sapphire/plugin-i18next",
|
|
3
|
-
"version": "8.0.0
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Plugin for @sapphire/framework to support i18next.",
|
|
5
5
|
"author": "@sapphire",
|
|
6
6
|
"license": "MIT",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@sapphire/utilities": "^3.18.2",
|
|
54
54
|
"@skyra/i18next-backend": "^2.0.5",
|
|
55
55
|
"chokidar": "^4.0.3",
|
|
56
|
-
"i18next": "^
|
|
56
|
+
"i18next": "^25.1.2"
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
59
59
|
"type": "git",
|
|
@@ -89,8 +89,8 @@
|
|
|
89
89
|
"@favware/cliff-jumper": "^6.0.0",
|
|
90
90
|
"@favware/rollup-type-bundler": "^4.0.0",
|
|
91
91
|
"concurrently": "^9.1.2",
|
|
92
|
-
"tsup": "^8.
|
|
93
|
-
"tsx": "^4.19.
|
|
92
|
+
"tsup": "^8.4.0",
|
|
93
|
+
"tsx": "^4.19.4",
|
|
94
94
|
"typedoc": "^0.26.11",
|
|
95
95
|
"typedoc-json-parser": "^10.2.0",
|
|
96
96
|
"typescript": "~5.4.5"
|