diff --git a/README.md b/README.md index 115fc7e..ad2392a 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,7 @@ Hi, read the `README.md` first (starting with [Install](#-install)). This emoji | `feat` | | โœจ | introduced a new feature | | `test` | | ๐Ÿงช | worked on tests | | `refactor` | | โ™ป๏ธ | refactored code, achieved the same with less | -| `init` | | ๐ŸŽ‰ | started a new project! | -| `initial` | | ๐ŸŽ‰ | this is for the default GitHub commit message (untested) | +| `init` | `initial` | | ๐ŸŽ‰ | started a new project! | | `perf` | | โšก | improved performance, achieve the same faster | | `config` | | โš™๏ธ | changed configuration files | | `style` | | ๐ŸŽจ | design changes, style changes | @@ -208,31 +207,37 @@ Commit message: #### Nested emojis -You can also nest emojis to create subtypes. After finding the type, `eemoji` will look for subtypes in the commit message. +You can also nest emojis to create subtypes. -Either using conventional commit scopes or just including the subtype in the commit message will work. +After finding the type, `eemoji` will look for subtypes in the commit message. -You can specify multiple emojis by separating them with commas and a **random** one will be chosen. +This is useful for conventional commit scopes, but you can include the subtype anywhere in the commit message. + +Notes: + +- the `'.'` is the fallback subtype +- specify multiple aliases for a type by separating them with pipes: `feat|feature` +- specify multiple emojis by separating them with commas and a **random** one will be chosen: `๐Ÿ’Ž,๐Ÿ’ฒ,๐Ÿ’ธ,๐Ÿ’ฐ` ```ts import { defineConfig } from 'eemoji' export default defineConfig({ emojis: { - fix: { + 'fix': { '.': '๐Ÿ”ง', 'typo': 'โœ๏ธ', 'bug': '๐Ÿ›' }, - chore: { + 'chore': { '.': '๐Ÿ—‘๏ธ', 'release': '๐Ÿ”–', 'cleanup': '๐Ÿงน', 'license': '๐Ÿ“œ', 'deps': '๐Ÿ“ฆ' }, - feat: 'โœจ', - bounty: '๐Ÿ’Ž,๐Ÿ’ฒ,๐Ÿ’ธ,๐Ÿ’ฐ' + 'feat|feature': 'โœจ', + 'bounty': '๐Ÿ’Ž,๐Ÿ’ฒ,๐Ÿ’ธ,๐Ÿ’ฐ' } }) ``` diff --git a/src/config.ts b/src/config.ts index d69d14e..51cb712 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,11 +3,13 @@ import process from 'node:process' import { name } from '../package.json' import emojis from './emojis.json' +type EmojiConfig = Partial & { + [key: string]: string | Record +} + export interface Config { format: string - emojis: { - [key: string]: string | Record - } + emojis: EmojiConfig } export const configTypes = [ @@ -21,10 +23,10 @@ export type JsFiles = typeof ConfigObject.prototype.jsFiles[number] export type JsonFiles = typeof ConfigObject.prototype.jsonFiles[number] export class ConfigObject { - defaultConfig: Config = { + defaultConfig = { format: '{emoji} {type}: {subject}', emojis, - } + } satisfies Config defaultTsConfig = `import { defineConfig } from 'eemoji' diff --git a/src/emojis.json b/src/emojis.json index 5e82969..f4f5e27 100644 --- a/src/emojis.json +++ b/src/emojis.json @@ -32,8 +32,7 @@ "feat": "โœจ", "test": "๐Ÿงช", "refactor": "โ™ป๏ธ", - "init": "๐ŸŽ‰", - "initial": "๐ŸŽ‰", + "init|initial": "๐ŸŽ‰", "up": "โฌ†๏ธ", "down": "โฌ‡๏ธ", "perf": "โšก", diff --git a/src/utils/emoji.ts b/src/utils/emoji.ts index 7d53c42..43c8628 100644 --- a/src/utils/emoji.ts +++ b/src/utils/emoji.ts @@ -21,23 +21,10 @@ export function eemojify(text: string, config: Config, DEBUG?: number): string { if (!type || !subject) throw new Error('Invalid commit message.') - let emoji: string | Record | undefined + let emoji = getEmoji(type, text, config, DEBUG) - // if there is an exclamatory mark, then it's a breaking change - if (text.includes('!') && config.emojis.breaking) - emoji = config.emojis.breaking - else - emoji = config.emojis[type.toLowerCase().replace(/\(.*\)/, '')] - - // if the emoji is an object, then it's a nested emoji - if (typeof emoji === 'object') { - emoji = getNestedEmoji(text, emoji) - if (DEBUG) - consola.log(`nested emoji: "${emoji}"`) - } - else if (DEBUG) { + if (DEBUG) consola.log(`emoji: "${emoji}"`) - } if (!emoji) throw new Error(`Emoji for type "${type}" not found.`) @@ -51,13 +38,34 @@ export function eemojify(text: string, config: Config, DEBUG?: number): string { .replace('{subject}', subject) } -function getNestedEmoji(text: string, emoji: Record): string | undefined { - const entries = Object.entries(emoji).filter(([key]) => key !== '.') +function getEmoji(type: string, text: string, config: Config, DEBUG?: number): string | undefined { + if (text.includes('!') && config.emojis.breaking) + return config.emojis.breaking + + const emojiKey = Object.keys(config.emojis).find(key => key.split('|').includes(type.toLowerCase().replace(/\(.*\)/, '').trim())) - for (const [key, value] of entries) { - if (text.includes(key)) - return value - } + if (!emojiKey) + return undefined - return emoji['.'] + const emoji = config.emojis[emojiKey] + + if (typeof emoji === 'object') { + if (DEBUG) + consola.log(`nested emoji: ${JSON.stringify(emoji)}`) + + const entries = Object.entries(emoji).filter(([key]) => key !== '.') + + for (const [key, value] of entries) { + if (key.split('|').some(k => text.toLowerCase().includes(k.toLowerCase()))) + return value + } + + return emoji['.'] + } + else if (typeof emoji === 'string') { + return emoji + } + else { + return undefined + } }