@miketromba/issy-core 0.1.0 → 0.1.1
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 +3 -2
- package/src/lib/autocomplete.ts +3 -3
- package/src/lib/formatDate.ts +22 -13
- package/src/lib/index.ts +39 -44
- package/src/lib/issues.ts +203 -203
- package/src/lib/query-parser.ts +69 -69
- package/src/lib/search.ts +244 -251
- package/src/lib/types.ts +27 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miketromba/issy-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Issue storage, search, and parsing for issy",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "bun test"
|
|
21
|
+
"test": "bun test",
|
|
22
|
+
"lint": "biome check src"
|
|
22
23
|
},
|
|
23
24
|
"exports": {
|
|
24
25
|
".": "./src/lib/index.ts"
|
package/src/lib/autocomplete.ts
CHANGED
|
@@ -61,7 +61,7 @@ export function getQuerySuggestions(
|
|
|
61
61
|
const textBeforeCursor = query.substring(0, cursor)
|
|
62
62
|
|
|
63
63
|
// Find the current token being typed
|
|
64
|
-
const { currentToken
|
|
64
|
+
const { currentToken } = findCurrentToken(textBeforeCursor)
|
|
65
65
|
|
|
66
66
|
// If we're in the middle of a qualifier (key:value)
|
|
67
67
|
if (currentToken.includes(':')) {
|
|
@@ -70,7 +70,7 @@ export function getQuerySuggestions(
|
|
|
70
70
|
const partialValue = currentToken.substring(colonIndex + 1)
|
|
71
71
|
|
|
72
72
|
// Check if it's a supported qualifier
|
|
73
|
-
if (QUALIFIER_KEYS.includes(qualifierKey
|
|
73
|
+
if ((QUALIFIER_KEYS as readonly string[]).includes(qualifierKey)) {
|
|
74
74
|
return getValueSuggestions(
|
|
75
75
|
qualifierKey,
|
|
76
76
|
partialValue,
|
|
@@ -119,7 +119,7 @@ function getValueSuggestions(
|
|
|
119
119
|
partialValue: string,
|
|
120
120
|
existingLabels?: string[]
|
|
121
121
|
): Suggestion[] {
|
|
122
|
-
const
|
|
122
|
+
const _suggestions: Suggestion[] = []
|
|
123
123
|
|
|
124
124
|
if (qualifierKey === 'label') {
|
|
125
125
|
// For labels, use existing labels if provided
|
package/src/lib/formatDate.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatDistanceToNow,
|
|
1
|
+
import { format, formatDistanceToNow, isValid, parseISO } from 'date-fns'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Format a date string for user-friendly display
|
|
@@ -6,20 +6,27 @@ import { formatDistanceToNow, format, parseISO, isValid } from 'date-fns'
|
|
|
6
6
|
*/
|
|
7
7
|
export function formatDisplayDate(dateStr: string | undefined): string {
|
|
8
8
|
if (!dateStr) return ''
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
try {
|
|
11
11
|
// Handle both YYYY-MM-DD and ISO formats
|
|
12
|
-
const date = dateStr.includes('T')
|
|
13
|
-
|
|
12
|
+
const date = dateStr.includes('T')
|
|
13
|
+
? parseISO(dateStr)
|
|
14
|
+
: parseISO(`${dateStr}T00:00:00`)
|
|
15
|
+
|
|
14
16
|
if (!isValid(date)) return dateStr
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
const now = new Date()
|
|
17
|
-
const diffInDays = Math.floor(
|
|
18
|
-
|
|
19
|
+
const diffInDays = Math.floor(
|
|
20
|
+
(now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24),
|
|
21
|
+
)
|
|
22
|
+
|
|
19
23
|
if (diffInDays < 7) {
|
|
20
24
|
// Within last week: "2 days ago", "3 hours ago"
|
|
21
25
|
// Remove "about" prefix for cleaner output
|
|
22
|
-
return formatDistanceToNow(date, { addSuffix: true }).replace(
|
|
26
|
+
return formatDistanceToNow(date, { addSuffix: true }).replace(
|
|
27
|
+
/^about /,
|
|
28
|
+
'',
|
|
29
|
+
)
|
|
23
30
|
} else if (diffInDays < 365) {
|
|
24
31
|
// Within last year: "Jan 15"
|
|
25
32
|
return format(date, 'MMM d')
|
|
@@ -37,15 +44,17 @@ export function formatDisplayDate(dateStr: string | undefined): string {
|
|
|
37
44
|
*/
|
|
38
45
|
export function formatFullDate(dateStr: string | undefined): string {
|
|
39
46
|
if (!dateStr) return ''
|
|
40
|
-
|
|
47
|
+
|
|
41
48
|
try {
|
|
42
|
-
const date = dateStr.includes('T')
|
|
43
|
-
|
|
49
|
+
const date = dateStr.includes('T')
|
|
50
|
+
? parseISO(dateStr)
|
|
51
|
+
: parseISO(`${dateStr}T00:00:00`)
|
|
52
|
+
|
|
44
53
|
if (!isValid(date)) return dateStr
|
|
45
|
-
|
|
54
|
+
|
|
46
55
|
// If it has time info, show it
|
|
47
56
|
if (dateStr.includes('T')) {
|
|
48
|
-
return format(date,
|
|
57
|
+
return format(date, "MMM d, yyyy 'at' h:mm a")
|
|
49
58
|
}
|
|
50
59
|
return format(date, 'MMM d, yyyy')
|
|
51
60
|
} catch {
|
package/src/lib/index.ts
CHANGED
|
@@ -5,53 +5,48 @@
|
|
|
5
5
|
* Used by both the API server and CLI.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
//
|
|
9
|
-
export type {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
CreateIssueInput,
|
|
14
|
-
UpdateIssueInput
|
|
15
|
-
} from './types'
|
|
16
|
-
|
|
8
|
+
// Autocomplete
|
|
9
|
+
export type { Suggestion } from './autocomplete'
|
|
10
|
+
export { getQuerySuggestions } from './autocomplete'
|
|
11
|
+
// Date formatting helpers (UI)
|
|
12
|
+
export { formatDisplayDate, formatFullDate } from './formatDate'
|
|
17
13
|
// Core issue operations
|
|
18
14
|
export {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
15
|
+
autoDetectIssuesDir,
|
|
16
|
+
closeIssue,
|
|
17
|
+
createIssue,
|
|
18
|
+
createSlug,
|
|
19
|
+
deleteIssue,
|
|
20
|
+
ensureIssuesDir,
|
|
21
|
+
formatDate,
|
|
22
|
+
generateFrontmatter,
|
|
23
|
+
getAllIssues,
|
|
24
|
+
getIssue,
|
|
25
|
+
getIssueFiles,
|
|
26
|
+
getIssueIdFromFilename,
|
|
27
|
+
getIssuesDir,
|
|
28
|
+
getNextIssueNumber,
|
|
29
|
+
parseFrontmatter,
|
|
30
|
+
reopenIssue,
|
|
31
|
+
setIssuesDir,
|
|
32
|
+
updateIssue,
|
|
37
33
|
} from './issues'
|
|
38
|
-
|
|
39
|
-
// Search functionality
|
|
40
|
-
export {
|
|
41
|
-
createSearchIndex,
|
|
42
|
-
searchIssues,
|
|
43
|
-
filterIssues,
|
|
44
|
-
filterAndSearchIssues,
|
|
45
|
-
filterByQuery
|
|
46
|
-
} from './search'
|
|
47
|
-
|
|
48
34
|
// Query parser
|
|
49
35
|
export type { ParsedQuery } from './query-parser'
|
|
50
36
|
export { parseQuery } from './query-parser'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
37
|
+
// Search functionality
|
|
38
|
+
export {
|
|
39
|
+
createSearchIndex,
|
|
40
|
+
filterAndSearchIssues,
|
|
41
|
+
filterByQuery,
|
|
42
|
+
filterIssues,
|
|
43
|
+
searchIssues,
|
|
44
|
+
} from './search'
|
|
45
|
+
// Types
|
|
46
|
+
export type {
|
|
47
|
+
CreateIssueInput,
|
|
48
|
+
Issue,
|
|
49
|
+
IssueFilters,
|
|
50
|
+
IssueFrontmatter,
|
|
51
|
+
UpdateIssueInput,
|
|
52
|
+
} from './types'
|