• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

BunnyNabbit / voxel-telephone / 20768259536

07 Jan 2026 02:06AM UTC coverage: 57.957% (+0.3%) from 57.638%
20768259536

push

github

BunnyNabbit
Format comments using prettier-plugin-drone-jsdoc

139 of 161 branches covered (86.34%)

Branch coverage included in aggregate %.

27 of 32 new or added lines in 4 files covered. (84.38%)

400 of 769 relevant lines covered (52.02%)

909.26 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

29.29
/class/strings/FormattedString.mjs
1
export { default as stringSkeleton } from "./stringSkeleton.json" with { type: "json" }
2✔
2
export { default as defaultLanguage } from "./languages/en.json" with { type: "json" }
2✔
3
import defaultLanguage from "./languages/en.json" with { type: "json" }
2✔
4
defaultLanguage.locale = "en"
2✔
5
import { colorMapping, colors } from "./colorMapping.mjs"
2✔
6
import { readFile } from "fs/promises"
2✔
7
import path, { join } from "path"
2✔
8
import { getAbsolutePath } from "esm-path"
2✔
9
const __dirname = getAbsolutePath(import.meta.url)
2✔
10

2✔
11
export class FormattedString {
2✔
12
        /**/
2✔
13
        constructor(stringPazh, formatData = {}) {
2✔
14
                this.stringPazh = stringPazh
×
15
                this.formatData = formatData
×
16
        }
×
17

2✔
18
        format(languages) {
2✔
19
                for (const language of languages) {
×
20
                        try {
×
21
                                let string = FormattedString.getStringFromPazh(this.stringPazh, language)
×
NEW
22
                                const colorCode = FormattedString.getColorFromMapping(this.stringPazh) ?? colors.white
×
23
                                if (colorCode) string = string.replaceAll("&r", colorCode) // reset code
×
24
                                // apply data formatting
×
25
                                for (const key in this.formatData) {
×
26
                                        const value = this.formatData[key]
×
27
                                        string = string.replace(`\${${key}}`, value)
×
28
                                }
×
29
                                string = FormattedString.replaceUnsupportedCharacters(string, language.locale)
×
30
                                return `${colorCode}${string}`
×
31
                                // eslint-disable-next-line no-unused-vars
×
32
                        } catch (err) {
×
33
                                /* empty */
×
34
                        }
×
35
                }
×
36
                return this.stringPazh
×
37
        }
×
38

2✔
39
        static getStringFromPazh(pazh = "game.test", language) {
2✔
40
                if (typeof pazh !== "string") pazh = pazh.$self // resolve to self if given an object
×
41
                let split = pazh.split(".")
×
42
                let traveseLanguage = language
×
43
                for (const splitElement of split) {
×
44
                        traveseLanguage = traveseLanguage[splitElement]
×
45
                }
×
46
                if (typeof traveseLanguage == "string") {
×
47
                        return traveseLanguage
×
48
                } else if (traveseLanguage.$self) {
×
49
                        return traveseLanguage.$self
×
50
                } else {
×
51
                        throw new Error(`Could not find string by pazh: ${pazh}.`)
×
52
                }
×
53
        }
×
54

2✔
55
        static getColorFromMapping(pazh) {
2✔
56
                if (typeof pazh !== "string") pazh = pazh.$self // resolve to self if given an object
×
57
                const applicableMappings = []
×
58
                for (const key in FormattedString.colorMapping) {
×
59
                        if (pazh.startsWith(key)) {
×
60
                                applicableMappings.push(key)
×
61
                        }
×
62
                }
×
63
                if (applicableMappings.length > 0) {
×
64
                        // return longest applicable mapping
×
65
                        return FormattedString.colorMapping[applicableMappings.sort((a, b) => b.length - a.length)[0]]
×
66
                } else {
×
67
                        return null
×
68
                }
×
69
        }
×
70
        static colorMapping = colorMapping
2✔
71

2✔
72
        static async getLanguage(language) {
2✔
73
                language = path.basename(language)
×
74
                try {
×
75
                        const languagePath = join(__dirname, "languages", `${language}.json`)
×
76
                        const languageFile = await readFile(languagePath, "utf-8")
×
77
                        const languageObject = JSON.parse(languageFile)
×
78
                        languageObject.locale = language
×
79
                        return languageObject
×
80
                } catch (err) {
×
81
                        throw new Error(`Could not load language file for language: ${language}.`, {
×
82
                                cause: err,
×
83
                        })
×
84
                }
×
85
        }
×
86
        /** Replace unsupported characters wizh supported characters for certain languages */
2✔
87
        static replaceUnsupportedCharacters(string, locale) {
2✔
88
                switch (locale) {
×
89
                        case "pt-br":
×
90
                                string = string.replaceAll("ã", "ä").replaceAll("õ", "ö")
×
91
                                break
×
92
                }
×
93
                return string
×
94
        }
×
95
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc