From bb50db4dec26cedfa90c4616e91b1f0b05a3dae8 Mon Sep 17 00:00:00 2001 From: ZomoXYZ Date: Tue, 29 Mar 2022 22:50:05 -0500 Subject: [PATCH] finish --- src/discord/index.ts | 132 ++++++++++++++++--------------------------- src/discord/types.ts | 4 +- src/discord/util.ts | 99 ++++++++++++++++++++++++++++++++ src/index.ts | 92 ++++++++++++------------------ src/types.ts | 11 +--- src/util.ts | 91 +++++++++++++++++++++++++++++ 6 files changed, 280 insertions(+), 149 deletions(-) create mode 100644 src/discord/util.ts create mode 100644 src/util.ts diff --git a/src/discord/index.ts b/src/discord/index.ts index 41966db..e1a6097 100644 --- a/src/discord/index.ts +++ b/src/discord/index.ts @@ -1,99 +1,67 @@ -import { MessageEmbed } from 'discord.js'; -import { template, resolveColor, bigString } from '..'; -import { embedObject, basicObjectString, authorData, footerData } from '../types'; - -export * from ".."; +import { basicObject, basicObjectStringable, embedObject, LangObj } from '../types'; +import { convertBasicObject, template } from '../util'; +import { embedDataType } from './types'; +import { embedObjEmbed } from './util'; +import Lang, { getLang } from '..'; /** - * converts embedObj to Discord.MessageEmbed + * reads language json as an object (could be embed or just string) + * @param id ex: discord.error.noActiveQueue + * @param argsraw list of key/value pairs to represent template values + * @param otherOptions values to be passed through to the return value + * @returns language value, defaults to `id` parameter */ -export function embedObjEmbed(embedObj: embedObject, args: basicObjectString = {}): MessageEmbed { - const embed = new MessageEmbed(), - { author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj; +function getEmbed(id: string, argsraw: basicObjectStringable = {}, otherOptions: basicObject = {}): embedDataType { - if (author !== undefined) { + const args = convertBasicObject(argsraw), + embedData: embedDataType = { + ...otherOptions, + embeds: [] + }; + + const keySpl = id.split('.').map(k => k.trim()).filter(k => k); - let authorFix: authorData; + let finding = getLang(); - if (typeof author === 'string') - authorFix = { - name: template(author, args) - }; - else { + for (const key of keySpl) { - const {name, iconURL, url} = author; + if (key in finding) { - authorFix = { - name: template(name, args) - }; + const found = finding[key]; - if (iconURL !== undefined) - authorFix.iconURL = template(iconURL, args); + if (typeof found === 'string') { + embedData.content = template(found, args); + break; + } - if (url !== undefined) - authorFix.url = template(url, args); + if (found.embed === true) { + const embedObj = found as embedObject, + {content} = embedObj, + embed = embedObjEmbed(embedObj, args); - } + embedData.embeds.push(embed); - embed.setAuthor(authorFix); + if (content !== undefined) + embedData.content = content; + return embedData; + } + + finding = found as LangObj; + + } else + break; + } - if (footer !== undefined) { + return embedData; +} - let footerFix: footerData; +export * from './types'; +export * from './util'; +export * from '..'; - if (typeof footer === 'string') { - - footerFix = { - text: template(footer, args) - }; - - } else { - - const {text, iconURL} = footer; - - footerFix = { - text: template(text, args) - }; - - if (iconURL !== undefined) - footerFix.iconURL = template(iconURL, args); - - } - - embed.setFooter(footerFix); - - } - - if (color !== undefined) - embed.setColor(resolveColor(template(color, args))); - - if (description !== undefined) - embed.setDescription(template(bigString(description), args)); - - if (image !== undefined) - embed.setImage(template(image, args)); - - if (thumbnail !== undefined) - embed.setThumbnail(template(thumbnail, args)); - - if (title !== undefined) - embed.setTitle(template(title, args)); - - if (url !== undefined) - embed.setURL(template(url, args)); - - if (timestamp === true) - embed.setTimestamp(); - else if (typeof timestamp === 'string') - embed.setTimestamp(new Date(template(timestamp, args))); - else if (timestamp !== false) - embed.setTimestamp(timestamp); - - fields?.forEach(field => { - embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline); - }); - - return embed; -} \ No newline at end of file +export default { + ...Lang, + getEmbed +}; \ No newline at end of file diff --git a/src/discord/types.ts b/src/discord/types.ts index bdb3962..e626324 100644 --- a/src/discord/types.ts +++ b/src/discord/types.ts @@ -6,4 +6,6 @@ import { MessageEmbed } from "discord.js"; export interface embedDataType { content?: string, embeds: MessageEmbed[] -} \ No newline at end of file +} + +export * from '../types'; diff --git a/src/discord/util.ts b/src/discord/util.ts new file mode 100644 index 0000000..33ffb3c --- /dev/null +++ b/src/discord/util.ts @@ -0,0 +1,99 @@ +import { MessageEmbed } from 'discord.js'; +import { template, resolveColor, bigString } from '../util'; +import { embedObject, basicObjectString, authorData, footerData } from '../types'; + +/** + * converts embedObj to Discord.MessageEmbed + */ +export function embedObjEmbed(embedObj: embedObject, args: basicObjectString = {}): MessageEmbed { + const embed = new MessageEmbed(), + { author, color, description, fields, footer, image, thumbnail, timestamp, title, url } = embedObj; + + if (author !== undefined) { + + let authorFix: authorData; + + if (typeof author === 'string') + authorFix = { + name: template(author, args) + }; + else { + + const {name, iconURL, url} = author; + + authorFix = { + name: template(name, args) + }; + + if (iconURL !== undefined) + authorFix.iconURL = template(iconURL, args); + + if (url !== undefined) + authorFix.url = template(url, args); + + } + + embed.setAuthor(authorFix); + + } + + if (footer !== undefined) { + + let footerFix: footerData; + + if (typeof footer === 'string') { + + footerFix = { + text: template(footer, args) + }; + + } else { + + const {text, iconURL} = footer; + + footerFix = { + text: template(text, args) + }; + + if (iconURL !== undefined) + footerFix.iconURL = template(iconURL, args); + + } + + embed.setFooter(footerFix); + + } + + if (color !== undefined) + embed.setColor(resolveColor(template(color, args))); + + if (description !== undefined) + embed.setDescription(template(bigString(description), args)); + + if (image !== undefined) + embed.setImage(template(image, args)); + + if (thumbnail !== undefined) + embed.setThumbnail(template(thumbnail, args)); + + if (title !== undefined) + embed.setTitle(template(title, args)); + + if (url !== undefined) + embed.setURL(template(url, args)); + + if (timestamp === true) + embed.setTimestamp(); + else if (typeof timestamp === 'string') + embed.setTimestamp(new Date(template(timestamp, args))); + else if (timestamp !== false) + embed.setTimestamp(timestamp); + + fields?.forEach(field => { + embed.addField(template(field.name, args), template(bigString(field.value), args), field.inline); + }); + + return embed; +} + +export * from '../util'; diff --git a/src/index.ts b/src/index.ts index 4a2f1f0..346ad6f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,76 +1,56 @@ +import { basicObjectStringable, embedObject, LangObj } from './types'; +import { convertBasicObject, embedObjStr, template } from './util'; -import { authorData, basicObject, basicObjectString, bigStringType, embedObject, footerData } from './types'; +/* MAIN */ +var LANG: LangObj = {}; -/** - * - * @param str - * @param args - * @returns - */ -export function template(str: string, args: basicObject): string { - - return str.replace(/{\w+}/g, str => { - - const key = str.substring(1, str.length-1); - - if (key in args) - return args[key]; - - return key; - - }); +export function setLang(lang: LangObj) { + LANG = lang; +} +export function getLang(): LangObj { + return LANG; } /** - * converts bigString to string + * reads language json (just strings) + * @param id ex: discord.error.noActiveQueue + * @param argsraw list of key/value pairs to represent template values + * @returns language value, defaults to `id` parameter */ -export function bigString(bigStr: bigStringType): string { - if (Array.isArray(bigStr)) - return bigStr.join('\n'); - return bigStr; -} +function get(id: string, argsraw: basicObjectStringable = {}): string { + const args = convertBasicObject(argsraw), + keySpl = id.split('.').map(k => k.trim()).filter(k => k); -/** - * converts Hex Color string to an RGB array - */ -export function resolveColor(color: string): [number, number, number] { - color = color.replace(/[^0-9a-f]/gi, ''); + let finding = LANG; - const colorNum: [number, number, number] = [0, 0, 0]; + for (const key of keySpl) { - if (color.length === 3 || color.length === 6) { + if (key in finding) { - const colorSplRaw = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color); + const found = finding[key]; - if (!colorSplRaw) - return colorNum; + if (typeof found === 'string') + return template(found, args); - const colorSpl = colorSplRaw.slice(1, 4); - - if (color.length === 3) - colorSpl.map(c => c + c); - - for (let i = 0; i < colorSpl.length && i < colorNum.length; i++) - colorNum[i] = parseInt(colorSpl[i], 16); + if (found.embed === true) + return embedObjStr(found as embedObject, args, id); + + finding = found as LangObj; + } else + break; + } - return colorNum; + return id; } -/** - * converts embedObj to a string if applicable - * @param fallback the string to use if no valid strings can be found - */ -export function embedObjStr(embedObj: embedObject, args: basicObjectString = {}, fallback = ''): string { +export default { + setLang, + get +}; - if (embedObj.content !== undefined) - return template(bigString(embedObj.content), args); - - if (embedObj.description !== undefined) - return template(bigString(embedObj.description), args); - - return fallback; -} \ No newline at end of file +export * from './types'; +export * from './util'; \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index a5b8ae1..3d963b3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,3 @@ - - /** * any indexable object */ @@ -89,11 +87,4 @@ export interface embedObject { * * `LANG > Language` */ -export type LangObj = { [keys:string]: LangObj | embedObject | string } - -/** - * the entire LANG object - * - * `LANG` - */ -export type LangObjWhole = { [langid:string]: LangObj } \ No newline at end of file +export type LangObj = { [keys:string]: LangObj | embedObject | string } \ No newline at end of file diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..e8a2878 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,91 @@ +import { basicObject, basicObjectString, basicObjectStringable, bigStringType, embedObject } from './types'; + +/** + * + * @param str + * @param args + * @returns + */ +export function template(str: string, args: basicObject): string { + + return str.replace(/{\w+}/g, str => { + + const key = str.substring(1, str.length-1); + + if (key in args) + return args[key]; + + return key; + + }); + +} + +/** + * converts bigString to string + */ +export function bigString(bigStr: bigStringType): string { + if (Array.isArray(bigStr)) + return bigStr.join('\n'); + return bigStr; +} + + +/** + * converts Hex Color string to an RGB array + */ +export function resolveColor(color: string): [number, number, number] { + color = color.replace(/[^0-9a-f]/gi, ''); + + const colorNum: [number, number, number] = [0, 0, 0]; + + if (color.length === 3 || color.length === 6) { + + const colorSplRaw = /([0-9a-f]{1,2})([0-9a-f]{1,2})([0-9a-f]{1,2})/.exec(color); + + if (!colorSplRaw) + return colorNum; + + const colorSpl = colorSplRaw.slice(1, 4); + + if (color.length === 3) + colorSpl.map(c => c + c); + + for (let i = 0; i < colorSpl.length && i < colorNum.length; i++) + colorNum[i] = parseInt(colorSpl[i], 16); + + } + + return colorNum; +} + +/** + * converts embedObj to a string if applicable + * @param fallback the string to use if no valid strings can be found + */ +export function embedObjStr(embedObj: embedObject, args: basicObjectString = {}, fallback = ''): string { + + if (embedObj.content !== undefined) + return template(bigString(embedObj.content), args); + + if (embedObj.description !== undefined) + return template(bigString(embedObj.description), args); + + return fallback; +} + +export function convertBasicObject(obj: basicObjectStringable): basicObjectString { + let ret: basicObjectString = {}; + for (const key in obj) { + const val = obj[key]; + if (typeof val === 'string') + ret[key] = val; + else if (typeof val === 'boolean') + ret[key] = val.toString(); + else if (typeof val === 'number') + ret[key] = val.toString(); + else + ret[key] = ''; + } + return ret; +} \ No newline at end of file