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

typeorm / typeorm / 19549987525

20 Nov 2025 08:11PM UTC coverage: 80.769% (+4.3%) from 76.433%
19549987525

push

github

web-flow
ci: run tests on commits to master and next (#11783)

Co-authored-by: Oleg "OSA413" Sokolov <OSA413@users.noreply.github.com>

26500 of 32174 branches covered (82.36%)

Branch coverage included in aggregate %.

91252 of 113615 relevant lines covered (80.32%)

88980.79 hits per line

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

92.59
/src/util/StringUtils.ts
1
import shajs from "sha.js"
26✔
2

26✔
3
/**
26✔
4
 * Converts string into camelCase.
26✔
5
 *
26✔
6
 * @see http://stackoverflow.com/questions/2970525/converting-any-string-into-camel-case
26✔
7
 */
26✔
8
export function camelCase(str: string, firstCapital: boolean = false): string {
30,113✔
9
    if (firstCapital) str = " " + str
30,113✔
10
    return str.replace(/^([A-Z])|[\s-_](\w)/g, function (match, p1, p2) {
30,113✔
11
        if (p2) return p2.toUpperCase()
21,877✔
12
        return p1.toLowerCase()
20!
13
    })
30,113✔
14
}
30,113✔
15

26✔
16
/**
26✔
17
 * Converts string into snake_case.
26✔
18
 *
26✔
19
 */
26✔
20
export function snakeCase(str: string): string {
33,274✔
21
    return (
33,274✔
22
        str
33,274✔
23
            // ABc -> a_bc
33,274✔
24
            .replace(/([A-Z])([A-Z])([a-z])/g, "$1_$2$3")
33,274✔
25
            // aC -> a_c
33,274✔
26
            .replace(/([a-z0-9])([A-Z])/g, "$1_$2")
33,274✔
27
            .toLowerCase()
33,274✔
28
    )
33,274✔
29
}
33,274✔
30

26✔
31
/**
26✔
32
 * Converts string into Title Case.
26✔
33
 *
26✔
34
 * @see http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
26✔
35
 */
26✔
36
export function titleCase(str: string): string {
13,006✔
37
    return str.replace(
13,006✔
38
        /\w\S*/g,
13,006✔
39
        (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(),
13,006✔
40
    )
13,006✔
41
}
13,006✔
42

26✔
43
/**
26✔
44
 * Builds abbreviated string from given string;
26✔
45
 */
26✔
46
export function abbreviate(str: string, abbrLettersCount: number = 1): string {
×
47
    const words = str
×
48
        .replace(/([a-z\xE0-\xFF])([A-Z\xC0\xDF])/g, "$1 $2")
×
49
        .split(" ")
×
50
    return words.reduce((res, word) => {
×
51
        res += word.substr(0, abbrLettersCount)
×
52
        return res
×
53
    }, "")
×
54
}
×
55

26✔
56
export interface IShortenOptions {
26✔
57
    /** String used to split "segments" of the alias/column name */
26✔
58
    separator?: string
26✔
59
    /** Maximum length of any "segment" */
26✔
60
    segmentLength?: number
26✔
61
    /** Length of any "term" in a "segment"; "OrderItem" is a segment, "Order" and "Items" are terms */
26✔
62
    termLength?: number
26✔
63
}
26✔
64

26✔
65
/**
26✔
66
 * Shorten a given `input`. Useful for RDBMS imposing a limit on the
26✔
67
 * maximum length of aliases and column names in SQL queries.
26✔
68
 *
26✔
69
 * @param input String to be shortened.
26✔
70
 * @param options Default to `4` for segments length, `2` for terms length, `'__'` as a separator.
26✔
71
 *
26✔
72
 * @return Shortened `input`.
26✔
73
 *
26✔
74
 * @example
26✔
75
 * // returns: "UsShCa__orde__mark__dire"
26✔
76
 * shorten('UserShoppingCart__order__market__director')
26✔
77
 *
26✔
78
 * // returns: "cat_wit_ver_lon_nam_pos_wit_ver_lon_nam_pos_wit_ver_lon_nam"
26✔
79
 * shorten(
26✔
80
 *   'category_with_very_long_name_posts_with_very_long_name_post_with_very_long_name',
26✔
81
 *   { separator: '_', segmentLength: 3 }
26✔
82
 * )
26✔
83
 *
26✔
84
 * // equals: UsShCa__orde__mark_market_id
26✔
85
 * `${shorten('UserShoppingCart__order__market')}_market_id`
26✔
86
 */
26✔
87
export function shorten(input: string, options: IShortenOptions = {}): string {
38✔
88
    const { segmentLength = 4, separator = "__", termLength = 2 } = options
38✔
89

38✔
90
    const segments = input.split(separator)
38✔
91
    const shortSegments = segments.reduce((acc: string[], val: string) => {
38✔
92
        // split the given segment into many terms based on an eventual camel cased name
306✔
93
        const segmentTerms = val
306✔
94
            .replace(/([a-z\xE0-\xFF])([A-Z\xC0-\xDF])/g, "$1 $2")
306✔
95
            .split(" ")
306✔
96
        // "OrderItemList" becomes "OrItLi", while "company" becomes "comp"
306✔
97
        const length = segmentTerms.length > 1 ? termLength : segmentLength
306!
98
        const shortSegment = segmentTerms
306✔
99
            .map((term) => term.substr(0, length))
306✔
100
            .join("")
306✔
101

306✔
102
        acc.push(shortSegment)
306✔
103
        return acc
306✔
104
    }, [])
38✔
105

38✔
106
    return shortSegments.join(separator)
38✔
107
}
38✔
108

26✔
109
interface IHashOptions {
26✔
110
    length?: number
26✔
111
}
26✔
112

26✔
113
/**
26✔
114
 * Returns a SHA-1 hex digest for internal IDs/aliases (not for cryptographic security)
26✔
115
 *
26✔
116
 * @param input String to be hashed.
26✔
117
 * @param options.length Optionally, shorten the output to desired length.
26✔
118
 */
26✔
119
export function hash(input: string, options: IHashOptions = {}): string {
4,380✔
120
    const hashFunction = shajs("sha1")
4,380✔
121
    hashFunction.update(input, "utf8")
4,380✔
122
    const hashedInput = hashFunction.digest("hex")
4,380✔
123
    if (options.length && options.length > 0) {
4,380✔
124
        return hashedInput.slice(0, options.length)
4,172✔
125
    }
4,172✔
126
    return hashedInput
208✔
127
}
208✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc