@miketromba/issy-core 0.5.5 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/autocomplete.ts +168 -164
- package/src/lib/browser.ts +5 -5
- package/src/lib/formatDate.ts +49 -49
- package/src/lib/index.ts +42 -42
- package/src/lib/issues.ts +336 -332
- package/src/lib/query-parser.ts +70 -70
- package/src/lib/search.ts +295 -288
- package/src/lib/types.ts +34 -34
package/src/lib/query-parser.ts
CHANGED
|
@@ -9,20 +9,20 @@
|
|
|
9
9
|
* Parsed query result containing extracted qualifiers and search text
|
|
10
10
|
*/
|
|
11
11
|
export interface ParsedQuery {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
qualifiers: Record<string, string>
|
|
13
|
+
searchText: string
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Supported qualifier keys
|
|
18
18
|
*/
|
|
19
19
|
const SUPPORTED_QUALIFIERS = new Set([
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
'is',
|
|
21
|
+
'priority',
|
|
22
|
+
'scope',
|
|
23
|
+
'type',
|
|
24
|
+
'label',
|
|
25
|
+
'sort'
|
|
26
26
|
])
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -48,42 +48,42 @@ const SUPPORTED_QUALIFIERS = new Set([
|
|
|
48
48
|
* // { qualifiers: { is: "open" }, searchText: "" }
|
|
49
49
|
*/
|
|
50
50
|
export function parseQuery(query: string): ParsedQuery {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const qualifiers: Record<string, string> = {}
|
|
52
|
+
const searchTextParts: string[] = []
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
if (!query || !query.trim()) {
|
|
55
|
+
return { qualifiers, searchText: '' }
|
|
56
|
+
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
// Split by spaces, but preserve quoted strings
|
|
59
|
+
const tokens = tokenizeQuery(query)
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
for (const token of tokens) {
|
|
62
|
+
// Check if token matches key:value pattern
|
|
63
|
+
const colonIndex = token.indexOf(':')
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (colonIndex > 0 && colonIndex < token.length - 1) {
|
|
66
|
+
const key = token.substring(0, colonIndex)
|
|
67
|
+
const value = token.substring(colonIndex + 1)
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
69
|
+
// Only extract if it's a supported qualifier
|
|
70
|
+
// Unknown qualifiers are treated as search text
|
|
71
|
+
if (SUPPORTED_QUALIFIERS.has(key)) {
|
|
72
|
+
qualifiers[key] = value
|
|
73
|
+
} else {
|
|
74
|
+
// Unknown qualifier format - treat as search text
|
|
75
|
+
searchTextParts.push(token)
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
// No colon or invalid format - treat as search text
|
|
79
|
+
searchTextParts.push(token)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
return {
|
|
84
|
+
qualifiers,
|
|
85
|
+
searchText: searchTextParts.join(' ').trim()
|
|
86
|
+
}
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
@@ -93,40 +93,40 @@ export function parseQuery(query: string): ParsedQuery {
|
|
|
93
93
|
* @returns Array of tokens
|
|
94
94
|
*/
|
|
95
95
|
function tokenizeQuery(query: string): string[] {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
const tokens: string[] = []
|
|
97
|
+
let currentToken = ''
|
|
98
|
+
let inQuotes = false
|
|
99
|
+
let quoteChar = ''
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
for (let i = 0; i < query.length; i++) {
|
|
102
|
+
const char = query[i]
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
104
|
+
if ((char === '"' || char === "'") && !inQuotes) {
|
|
105
|
+
// Start of quoted string
|
|
106
|
+
inQuotes = true
|
|
107
|
+
quoteChar = char
|
|
108
|
+
// Don't include the quote in the token
|
|
109
|
+
} else if (char === quoteChar && inQuotes) {
|
|
110
|
+
// End of quoted string
|
|
111
|
+
inQuotes = false
|
|
112
|
+
quoteChar = ''
|
|
113
|
+
// Don't include the quote in the token
|
|
114
|
+
} else if (char === ' ' && !inQuotes) {
|
|
115
|
+
// Space outside quotes - end of token
|
|
116
|
+
if (currentToken) {
|
|
117
|
+
tokens.push(currentToken)
|
|
118
|
+
currentToken = ''
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
// Regular character - add to current token
|
|
122
|
+
currentToken += char
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
// Add final token if exists
|
|
127
|
+
if (currentToken) {
|
|
128
|
+
tokens.push(currentToken)
|
|
129
|
+
}
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
return tokens
|
|
132
132
|
}
|