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

MrSwitch / dare / #72

06 Jun 2026 07:58PM UTC coverage: 69.143% (-30.9%) from 100.0%
#72

push

web-flow
feat(import-engine): move engines out to their own import path, BREAKING CHANGE (#454)

* feat(postgres): move postgres out to it's own endpoint, BREAKING CHANGE

* style(prettier): fix

* style(ts): fix

* test: fixes

* docs: update README

* docs: update README

* fix(import): migrate LIKE keyword to configurable prop

* feat(import): define mysql5.7 (incl 5.6) legacy import paths, #455

* fix(import): test using wrong dependency

* feat: pluggable json formatter

* fix: issue

* chore: address comments

* fix: issue

* fix: address comments

* fix: address comments, tidy ts

* feat(import): abstract json perfix, operator and formatting

* chore: tidy

* fix(import): abstract DML changes

* feat(import): abstract applyAliasesOnUpdate

* feat(import): abstract sql_fulltext_wildcard

* feat(import): abstract sql_fulltext_wildcard

* feat(import): abstract fulltext sign operators

* chore(postgres): migrate to postgres16 for future proofing

* docs(README): add info about engine specific import paths

* Update README.md

* docs(README): update

* fix: address comments

* fix: prettier

339 of 499 branches covered (67.94%)

Branch coverage included in aggregate %.

487 of 516 new or added lines in 6 files covered. (94.38%)

1497 existing lines in 23 files now uncovered.

3439 of 4965 relevant lines covered (69.26%)

4.28 hits per line

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

28.67
/src/utils/unwrap_field.js
1
/* eslint-disable prefer-named-capture-group */
9✔
2
import DareError from './error.js';
9✔
3

9✔
4
export default function unwrap_field(expression, allowValue = true) {
9✔
5
        if (typeof expression === 'string') {
6✔
6
                let m;
6✔
7
                let str = expression;
6✔
8
                let suffix = '';
6✔
9
                let prefix = '';
6✔
10

6✔
11
                if (str.length > 200) {
6!
UNCOV
12
                        throw new DareError(
×
UNCOV
13
                                DareError.INVALID_REFERENCE,
×
UNCOV
14
                                `The field definition '${expression}' is too long.`
×
UNCOV
15
                        );
×
UNCOV
16
                }
×
17

6✔
18
                // Match a function, "STRING_DENOTES_FUNCTION(.*)"
6✔
19
                while ((m = str.match(/^(!?[_a-z]+\()(.*)(\))$/i))) {
6!
UNCOV
20
                        // Change the string to match the inner string...
×
UNCOV
21
                        str = m[2];
×
UNCOV
22

×
UNCOV
23
                        // Capture the suffix,prefix
×
UNCOV
24
                        prefix += m[1];
×
UNCOV
25
                        suffix = m[3] + suffix;
×
UNCOV
26

×
UNCOV
27
                        let int_m;
×
UNCOV
28

×
UNCOV
29
                        // Remove suffix tweaks
×
UNCOV
30
                        if ((int_m = str.match(/(.*)(\s+ORDER BY 1)\s*$/))) {
×
UNCOV
31
                                suffix = int_m[2] + suffix;
×
UNCOV
32
                                str = int_m[1];
×
UNCOV
33
                        }
×
UNCOV
34

×
UNCOV
35
                        // Split out comma variables from front
×
UNCOV
36
                        while (
×
UNCOV
37
                                (int_m = str.match(
×
UNCOV
38
                                        /^(?<prefix>((?<quote>["'])[^"';\\]*\k<quote>),\s*)(?<body>.+)$/i
×
UNCOV
39
                                ))
×
UNCOV
40
                        ) {
×
UNCOV
41
                                str = int_m?.groups?.body;
×
UNCOV
42
                                prefix += int_m?.groups?.prefix;
×
UNCOV
43
                        }
×
UNCOV
44

×
UNCOV
45
                        // Split out comma variables
×
UNCOV
46
                        while (
×
UNCOV
47
                                (int_m = str.match(
×
UNCOV
48
                                        /^(.*)((,|\sAS)\s*(?<suffix>(?<quote>["'])?[\s\w%./-]*\k<quote>))$/
×
UNCOV
49
                                ))
×
UNCOV
50
                        ) {
×
UNCOV
51
                                /*
×
UNCOV
52
                                 * If unquoted parameter
×
UNCOV
53
                                 * Ensure no lowercase strings (i.e. column names)
×
UNCOV
54
                                 */
×
UNCOV
55
                                if (
×
UNCOV
56
                                        !int_m.groups.quote &&
×
UNCOV
57
                                        int_m.groups.suffix?.match(/[a-z]/)
×
UNCOV
58
                                ) {
×
UNCOV
59
                                        // Is this a valid field
×
UNCOV
60
                                        throw new DareError(
×
UNCOV
61
                                                DareError.INVALID_REFERENCE,
×
UNCOV
62
                                                `The field definition '${expression}' is invalid.`
×
UNCOV
63
                                        );
×
UNCOV
64
                                }
×
UNCOV
65

×
UNCOV
66
                                str = int_m[1].trim();
×
UNCOV
67
                                suffix = int_m[2] + suffix;
×
UNCOV
68
                        }
×
UNCOV
69

×
UNCOV
70
                        /*
×
UNCOV
71
                         * Deal with math and operators against a value
×
UNCOV
72
                         */
×
UNCOV
73
                        const int_x = str.match(
×
UNCOV
74
                                /(.*)(\s((\*|\/|>|<|=|<=|>=|<>|!=)\s([\d.]+|((?<quote>["'])[\s\w%.-]*\k<quote>))|is null|is not null))$/i
×
UNCOV
75
                        );
×
UNCOV
76

×
UNCOV
77
                        if (int_x) {
×
UNCOV
78
                                str = int_x[1];
×
UNCOV
79
                                suffix = int_x[2] + suffix;
×
UNCOV
80
                        }
×
UNCOV
81
                }
×
82

6✔
83
                // Does the string start with a negation (!) ?
6✔
84
                if (str && str.startsWith('!')) {
6!
UNCOV
85
                        prefix += '!';
×
UNCOV
86
                        str = str.slice(1);
×
UNCOV
87
                }
×
88

6✔
89
                // Remove any additional prefix in a function.. i.e. "YEAR_MONTH FROM " from "EXTRACT(YEAR_MONTH FROM field)"
6✔
90
                if (prefix && str && (m = str.match(/^[\sA-Z_]+\s/))) {
6!
UNCOV
91
                        prefix += m[0];
×
UNCOV
92
                        str = str.slice(m[0].length);
×
UNCOV
93
                }
×
94

6✔
95
                // Finally check that the str is a match
6✔
96
                if (str.match(/^[\w$*.]*$/)) {
6✔
97
                        const field = str;
6✔
98
                        const a = str.split('.');
6✔
99
                        const field_name = a.pop();
6✔
100
                        const field_path = a.join('.');
6✔
101

6✔
102
                        const resp = {
6✔
103
                                field,
6✔
104
                                field_name,
6✔
105
                                field_path,
6✔
106
                                prefix,
6✔
107
                                suffix,
6✔
108
                        };
6✔
109

6✔
110
                        // This passes the test
6✔
111
                        return resp;
6✔
112
                }
6✔
UNCOV
113

×
UNCOV
114
                // Return value...
×
UNCOV
115
                if (allowValue) {
×
UNCOV
116
                        if (str.length === 0 || /^(["'])[\s\w]+\1$/.test(str)) {
×
UNCOV
117
                                return {
×
UNCOV
118
                                        value: expression,
×
UNCOV
119
                                };
×
UNCOV
120
                        }
×
UNCOV
121
                }
×
122
        }
6✔
UNCOV
123

×
UNCOV
124
        // Else if this is not a reference to a db field, pass as a value
×
UNCOV
125
        else if (
×
UNCOV
126
                (allowValue && typeof expression === 'number') ||
×
UNCOV
127
                expression === null ||
×
UNCOV
128
                typeof expression === 'boolean'
×
UNCOV
129
        ) {
×
UNCOV
130
                return {
×
UNCOV
131
                        value: expression,
×
UNCOV
132
                };
×
UNCOV
133
        }
×
UNCOV
134

×
UNCOV
135
        // Is this a valid field
×
UNCOV
136
        throw new DareError(
×
UNCOV
137
                DareError.INVALID_REFERENCE,
×
UNCOV
138
                `The field definition '${expression}' is invalid.`
×
UNCOV
139
        );
×
140
}
6✔
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