@task-mcp/shared 0.1.0
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/dist/algorithms/critical-path.d.ts +46 -0
- package/dist/algorithms/critical-path.d.ts.map +1 -0
- package/dist/algorithms/critical-path.js +308 -0
- package/dist/algorithms/critical-path.js.map +1 -0
- package/dist/algorithms/critical-path.test.d.ts +2 -0
- package/dist/algorithms/critical-path.test.d.ts.map +1 -0
- package/dist/algorithms/critical-path.test.js +194 -0
- package/dist/algorithms/critical-path.test.js.map +1 -0
- package/dist/algorithms/index.d.ts +3 -0
- package/dist/algorithms/index.d.ts.map +1 -0
- package/dist/algorithms/index.js +3 -0
- package/dist/algorithms/index.js.map +1 -0
- package/dist/algorithms/topological-sort.d.ts +41 -0
- package/dist/algorithms/topological-sort.d.ts.map +1 -0
- package/dist/algorithms/topological-sort.js +168 -0
- package/dist/algorithms/topological-sort.js.map +1 -0
- package/dist/algorithms/topological-sort.test.d.ts +2 -0
- package/dist/algorithms/topological-sort.test.d.ts.map +1 -0
- package/dist/algorithms/topological-sort.test.js +162 -0
- package/dist/algorithms/topological-sort.test.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/index.d.ts +4 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +7 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/project.d.ts +55 -0
- package/dist/schemas/project.d.ts.map +1 -0
- package/dist/schemas/project.js +48 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/task.d.ts +124 -0
- package/dist/schemas/task.d.ts.map +1 -0
- package/dist/schemas/task.js +89 -0
- package/dist/schemas/task.js.map +1 -0
- package/dist/schemas/view.d.ts +44 -0
- package/dist/schemas/view.d.ts.map +1 -0
- package/dist/schemas/view.js +33 -0
- package/dist/schemas/view.js.map +1 -0
- package/dist/utils/date.d.ts +25 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/date.js +103 -0
- package/dist/utils/date.js.map +1 -0
- package/dist/utils/date.test.d.ts +2 -0
- package/dist/utils/date.test.d.ts.map +1 -0
- package/dist/utils/date.test.js +138 -0
- package/dist/utils/date.test.js.map +1 -0
- package/dist/utils/id.d.ts +27 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +41 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/natural-language.d.ts +12 -0
- package/dist/utils/natural-language.d.ts.map +1 -0
- package/dist/utils/natural-language.js +112 -0
- package/dist/utils/natural-language.js.map +1 -0
- package/dist/utils/natural-language.test.d.ts +2 -0
- package/dist/utils/natural-language.test.d.ts.map +1 -0
- package/dist/utils/natural-language.test.js +132 -0
- package/dist/utils/natural-language.test.js.map +1 -0
- package/package.json +46 -0
- package/src/algorithms/critical-path.test.ts +241 -0
- package/src/algorithms/critical-path.ts +413 -0
- package/src/algorithms/index.ts +17 -0
- package/src/algorithms/topological-sort.test.ts +190 -0
- package/src/algorithms/topological-sort.ts +204 -0
- package/src/index.ts +8 -0
- package/src/schemas/index.ts +30 -0
- package/src/schemas/project.ts +62 -0
- package/src/schemas/task.ts +116 -0
- package/src/schemas/view.ts +46 -0
- package/src/utils/date.test.ts +160 -0
- package/src/utils/date.ts +119 -0
- package/src/utils/id.ts +45 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/natural-language.test.ts +154 -0
- package/src/utils/natural-language.ts +125 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
// Priority levels
|
|
3
|
+
export const Priority = type("'critical' | 'high' | 'medium' | 'low'");
|
|
4
|
+
// Task status with clear state machine
|
|
5
|
+
export const TaskStatus = type("'pending' | 'in_progress' | 'blocked' | 'completed' | 'cancelled'");
|
|
6
|
+
// Dependency relationship types
|
|
7
|
+
export const DependencyType = type("'blocks' | 'blocked_by' | 'related'");
|
|
8
|
+
// A single dependency link
|
|
9
|
+
export const Dependency = type({
|
|
10
|
+
taskId: "string",
|
|
11
|
+
type: DependencyType,
|
|
12
|
+
"reason?": "string",
|
|
13
|
+
});
|
|
14
|
+
// Time estimation
|
|
15
|
+
export const TimeEstimate = type({
|
|
16
|
+
"optimistic?": "number", // minutes
|
|
17
|
+
"expected?": "number", // minutes
|
|
18
|
+
"pessimistic?": "number", // minutes
|
|
19
|
+
"confidence?": "'low' | 'medium' | 'high'",
|
|
20
|
+
});
|
|
21
|
+
// Recurrence pattern
|
|
22
|
+
export const Recurrence = type({
|
|
23
|
+
pattern: "'daily' | 'weekly' | 'monthly' | 'after_completion'",
|
|
24
|
+
"interval?": "number", // every N days/weeks/months
|
|
25
|
+
"daysOfWeek?": "number[]", // 0-6 for weekly
|
|
26
|
+
"endDate?": "string",
|
|
27
|
+
});
|
|
28
|
+
// Core Task schema
|
|
29
|
+
export const Task = type({
|
|
30
|
+
id: "string",
|
|
31
|
+
title: "string",
|
|
32
|
+
"description?": "string",
|
|
33
|
+
status: TaskStatus,
|
|
34
|
+
priority: Priority,
|
|
35
|
+
projectId: "string",
|
|
36
|
+
// Dependencies
|
|
37
|
+
"dependencies?": Dependency.array(),
|
|
38
|
+
// Time tracking
|
|
39
|
+
"estimate?": TimeEstimate,
|
|
40
|
+
"actualMinutes?": "number",
|
|
41
|
+
"dueDate?": "string", // ISO date string
|
|
42
|
+
"startDate?": "string", // When task can start
|
|
43
|
+
"startedAt?": "string",
|
|
44
|
+
"completedAt?": "string",
|
|
45
|
+
// Organization
|
|
46
|
+
"contexts?": "string[]", // e.g., ["focus", "review"]
|
|
47
|
+
"tags?": "string[]",
|
|
48
|
+
// Recurrence
|
|
49
|
+
"recurrence?": Recurrence,
|
|
50
|
+
// Metadata
|
|
51
|
+
createdAt: "string",
|
|
52
|
+
updatedAt: "string",
|
|
53
|
+
// Computed fields (populated at runtime)
|
|
54
|
+
"criticalPath?": "boolean",
|
|
55
|
+
"slack?": "number", // Minutes of slack time
|
|
56
|
+
"earliestStart?": "number", // Minutes from project start
|
|
57
|
+
"latestStart?": "number",
|
|
58
|
+
});
|
|
59
|
+
// Task creation input (minimal required fields)
|
|
60
|
+
export const TaskCreateInput = type({
|
|
61
|
+
title: "string",
|
|
62
|
+
"description?": "string",
|
|
63
|
+
"projectId?": "string",
|
|
64
|
+
"priority?": Priority,
|
|
65
|
+
"dependencies?": Dependency.array(),
|
|
66
|
+
"estimate?": TimeEstimate,
|
|
67
|
+
"dueDate?": "string",
|
|
68
|
+
"startDate?": "string",
|
|
69
|
+
"contexts?": "string[]",
|
|
70
|
+
"tags?": "string[]",
|
|
71
|
+
"recurrence?": Recurrence,
|
|
72
|
+
});
|
|
73
|
+
// Task update input
|
|
74
|
+
export const TaskUpdateInput = type({
|
|
75
|
+
"title?": "string",
|
|
76
|
+
"description?": "string",
|
|
77
|
+
"status?": TaskStatus,
|
|
78
|
+
"priority?": Priority,
|
|
79
|
+
"projectId?": "string",
|
|
80
|
+
"dependencies?": Dependency.array(),
|
|
81
|
+
"estimate?": TimeEstimate,
|
|
82
|
+
"actualMinutes?": "number",
|
|
83
|
+
"dueDate?": "string",
|
|
84
|
+
"startDate?": "string",
|
|
85
|
+
"contexts?": "string[]",
|
|
86
|
+
"tags?": "string[]",
|
|
87
|
+
"recurrence?": Recurrence,
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/schemas/task.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const SmartViewFilter: import("arktype/internal/methods/object.ts").ObjectType<{
|
|
2
|
+
statuses?: ("pending" | "in_progress" | "blocked" | "completed" | "cancelled")[];
|
|
3
|
+
priorities?: ("critical" | "high" | "medium" | "low")[];
|
|
4
|
+
contexts?: string[];
|
|
5
|
+
tags?: string[];
|
|
6
|
+
projectIds?: string[];
|
|
7
|
+
dueBefore?: string;
|
|
8
|
+
dueAfter?: string;
|
|
9
|
+
isBlocked?: boolean;
|
|
10
|
+
isCriticalPath?: boolean;
|
|
11
|
+
hasNoDependencies?: boolean;
|
|
12
|
+
search?: string;
|
|
13
|
+
}, {}>;
|
|
14
|
+
export type SmartViewFilter = typeof SmartViewFilter.infer;
|
|
15
|
+
export declare const SortField: import("arktype/internal/methods/string.ts").StringType<"title" | "priority" | "createdAt" | "dueDate" | "criticalPath" | "slack", {}>;
|
|
16
|
+
export type SortField = typeof SortField.infer;
|
|
17
|
+
export declare const SortOrder: import("arktype/internal/methods/string.ts").StringType<"asc" | "desc", {}>;
|
|
18
|
+
export type SortOrder = typeof SortOrder.infer;
|
|
19
|
+
export declare const SmartView: import("arktype/internal/methods/object.ts").ObjectType<{
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
filter: {
|
|
23
|
+
statuses?: ("pending" | "in_progress" | "blocked" | "completed" | "cancelled")[];
|
|
24
|
+
priorities?: ("critical" | "high" | "medium" | "low")[];
|
|
25
|
+
contexts?: string[];
|
|
26
|
+
tags?: string[];
|
|
27
|
+
projectIds?: string[];
|
|
28
|
+
dueBefore?: string;
|
|
29
|
+
dueAfter?: string;
|
|
30
|
+
isBlocked?: boolean;
|
|
31
|
+
isCriticalPath?: boolean;
|
|
32
|
+
hasNoDependencies?: boolean;
|
|
33
|
+
search?: string;
|
|
34
|
+
};
|
|
35
|
+
createdAt: string;
|
|
36
|
+
updatedAt: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
sortBy?: "title" | "priority" | "createdAt" | "dueDate" | "criticalPath" | "slack";
|
|
39
|
+
sortOrder?: "asc" | "desc";
|
|
40
|
+
}, {}>;
|
|
41
|
+
export type SmartView = typeof SmartView.infer;
|
|
42
|
+
export declare const BuiltInView: import("arktype/internal/methods/string.ts").StringType<"blocked" | "today" | "this_week" | "critical_path" | "quick_wins" | "all", {}>;
|
|
43
|
+
export type BuiltInView = typeof BuiltInView.infer;
|
|
44
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/schemas/view.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe;;;;;;;;;;;;MAY1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,KAAK,CAAC;AAG3D,eAAO,MAAM,SAAS,wIAErB,CAAC;AACF,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAE/C,eAAO,MAAM,SAAS,6EAAyB,CAAC;AAChD,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAG/C,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;MASpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,KAAK,CAAC;AAG/C,eAAO,MAAM,WAAW,yIAEvB,CAAC;AACF,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,KAAK,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import { Priority, TaskStatus } from "./task.js";
|
|
3
|
+
// Smart View filter
|
|
4
|
+
export const SmartViewFilter = type({
|
|
5
|
+
"statuses?": TaskStatus.array(),
|
|
6
|
+
"priorities?": Priority.array(),
|
|
7
|
+
"contexts?": "string[]",
|
|
8
|
+
"tags?": "string[]",
|
|
9
|
+
"projectIds?": "string[]",
|
|
10
|
+
"dueBefore?": "string",
|
|
11
|
+
"dueAfter?": "string",
|
|
12
|
+
"isBlocked?": "boolean",
|
|
13
|
+
"isCriticalPath?": "boolean",
|
|
14
|
+
"hasNoDependencies?": "boolean",
|
|
15
|
+
"search?": "string", // Search in title/description
|
|
16
|
+
});
|
|
17
|
+
// Sort options
|
|
18
|
+
export const SortField = type("'priority' | 'dueDate' | 'createdAt' | 'criticalPath' | 'slack' | 'title'");
|
|
19
|
+
export const SortOrder = type("'asc' | 'desc'");
|
|
20
|
+
// Smart View definition
|
|
21
|
+
export const SmartView = type({
|
|
22
|
+
id: "string",
|
|
23
|
+
name: "string",
|
|
24
|
+
"description?": "string",
|
|
25
|
+
filter: SmartViewFilter,
|
|
26
|
+
"sortBy?": SortField,
|
|
27
|
+
"sortOrder?": SortOrder,
|
|
28
|
+
createdAt: "string",
|
|
29
|
+
updatedAt: "string",
|
|
30
|
+
});
|
|
31
|
+
// Built-in view names
|
|
32
|
+
export const BuiltInView = type("'today' | 'this_week' | 'blocked' | 'critical_path' | 'quick_wins' | 'all'");
|
|
33
|
+
//# sourceMappingURL=view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/schemas/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEjD,oBAAoB;AACpB,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,UAAU,CAAC,KAAK,EAAE;IAC/B,aAAa,EAAE,QAAQ,CAAC,KAAK,EAAE;IAC/B,WAAW,EAAE,UAAU;IACvB,OAAO,EAAE,UAAU;IACnB,aAAa,EAAE,UAAU;IACzB,YAAY,EAAE,QAAQ;IACtB,WAAW,EAAE,QAAQ;IACrB,YAAY,EAAE,SAAS;IACvB,iBAAiB,EAAE,SAAS;IAC5B,oBAAoB,EAAE,SAAS;IAC/B,SAAS,EAAE,QAAQ,EAAE,8BAA8B;CACpD,CAAC,CAAC;AAGH,eAAe;AACf,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAC3B,2EAA2E,CAC5E,CAAC;AAGF,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAGhD,wBAAwB;AACxB,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;IAC5B,EAAE,EAAE,QAAQ;IACZ,IAAI,EAAE,QAAQ;IACd,cAAc,EAAE,QAAQ;IACxB,MAAM,EAAE,eAAe;IACvB,SAAS,EAAE,SAAS;IACpB,YAAY,EAAE,SAAS;IACvB,SAAS,EAAE,QAAQ;IACnB,SAAS,EAAE,QAAQ;CACpB,CAAC,CAAC;AAGH,sBAAsB;AACtB,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAC7B,4EAA4E,CAC7E,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get current ISO timestamp
|
|
3
|
+
*/
|
|
4
|
+
export declare function now(): string;
|
|
5
|
+
/**
|
|
6
|
+
* Parse relative date strings
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseRelativeDate(input: string): Date | null;
|
|
9
|
+
/**
|
|
10
|
+
* Format date as YYYY-MM-DD
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatDate(date: Date): string;
|
|
13
|
+
/**
|
|
14
|
+
* Check if a date is today
|
|
15
|
+
*/
|
|
16
|
+
export declare function isToday(date: Date | string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Check if a date is before today
|
|
19
|
+
*/
|
|
20
|
+
export declare function isPastDue(date: Date | string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a date is within the next N days
|
|
23
|
+
*/
|
|
24
|
+
export declare function isWithinDays(date: Date | string, days: number): boolean;
|
|
25
|
+
//# sourceMappingURL=date.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAkE5D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAQpD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO,CAKtD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAOvE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get current ISO timestamp
|
|
3
|
+
*/
|
|
4
|
+
export function now() {
|
|
5
|
+
return new Date().toISOString();
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse relative date strings
|
|
9
|
+
*/
|
|
10
|
+
export function parseRelativeDate(input) {
|
|
11
|
+
const today = new Date();
|
|
12
|
+
today.setHours(0, 0, 0, 0);
|
|
13
|
+
const lower = input.toLowerCase().trim();
|
|
14
|
+
// Today
|
|
15
|
+
if (lower === "today" || lower === "오늘") {
|
|
16
|
+
return today;
|
|
17
|
+
}
|
|
18
|
+
// Tomorrow
|
|
19
|
+
if (lower === "tomorrow" || lower === "내일") {
|
|
20
|
+
const d = new Date(today);
|
|
21
|
+
d.setDate(d.getDate() + 1);
|
|
22
|
+
return d;
|
|
23
|
+
}
|
|
24
|
+
// Yesterday
|
|
25
|
+
if (lower === "yesterday" || lower === "어제") {
|
|
26
|
+
const d = new Date(today);
|
|
27
|
+
d.setDate(d.getDate() - 1);
|
|
28
|
+
return d;
|
|
29
|
+
}
|
|
30
|
+
// Next week
|
|
31
|
+
if (lower === "next week" || lower === "다음주") {
|
|
32
|
+
const d = new Date(today);
|
|
33
|
+
d.setDate(d.getDate() + 7);
|
|
34
|
+
return d;
|
|
35
|
+
}
|
|
36
|
+
// In N days
|
|
37
|
+
const inDaysMatch = lower.match(/^in (\d+) days?$/);
|
|
38
|
+
if (inDaysMatch) {
|
|
39
|
+
const d = new Date(today);
|
|
40
|
+
d.setDate(d.getDate() + parseInt(inDaysMatch[1], 10));
|
|
41
|
+
return d;
|
|
42
|
+
}
|
|
43
|
+
// N일 후
|
|
44
|
+
const koreanDaysMatch = lower.match(/^(\d+)일\s*후$/);
|
|
45
|
+
if (koreanDaysMatch) {
|
|
46
|
+
const d = new Date(today);
|
|
47
|
+
d.setDate(d.getDate() + parseInt(koreanDaysMatch[1], 10));
|
|
48
|
+
return d;
|
|
49
|
+
}
|
|
50
|
+
// Weekday names
|
|
51
|
+
const weekdays = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
|
|
52
|
+
const weekdayIndex = weekdays.indexOf(lower);
|
|
53
|
+
if (weekdayIndex !== -1) {
|
|
54
|
+
const d = new Date(today);
|
|
55
|
+
const currentDay = d.getDay();
|
|
56
|
+
const daysUntil = (weekdayIndex - currentDay + 7) % 7 || 7;
|
|
57
|
+
d.setDate(d.getDate() + daysUntil);
|
|
58
|
+
return d;
|
|
59
|
+
}
|
|
60
|
+
// Try parsing as ISO date
|
|
61
|
+
const parsed = new Date(input);
|
|
62
|
+
if (!isNaN(parsed.getTime())) {
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Format date as YYYY-MM-DD
|
|
69
|
+
*/
|
|
70
|
+
export function formatDate(date) {
|
|
71
|
+
return date.toISOString().split("T")[0];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if a date is today
|
|
75
|
+
*/
|
|
76
|
+
export function isToday(date) {
|
|
77
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
78
|
+
const today = new Date();
|
|
79
|
+
return (d.getFullYear() === today.getFullYear() &&
|
|
80
|
+
d.getMonth() === today.getMonth() &&
|
|
81
|
+
d.getDate() === today.getDate());
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if a date is before today
|
|
85
|
+
*/
|
|
86
|
+
export function isPastDue(date) {
|
|
87
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
88
|
+
const today = new Date();
|
|
89
|
+
today.setHours(0, 0, 0, 0);
|
|
90
|
+
return d < today;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if a date is within the next N days
|
|
94
|
+
*/
|
|
95
|
+
export function isWithinDays(date, days) {
|
|
96
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
97
|
+
const today = new Date();
|
|
98
|
+
today.setHours(0, 0, 0, 0);
|
|
99
|
+
const future = new Date(today);
|
|
100
|
+
future.setDate(future.getDate() + days);
|
|
101
|
+
return d >= today && d <= future;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.js","sourceRoot":"","sources":["../../src/utils/date.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,GAAG;IACjB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAE3B,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAEzC,QAAQ;IACR,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,WAAW;IACX,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,YAAY;IACZ,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,YAAY;IACZ,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,YAAY;IACZ,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO;IACP,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACpD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,gBAAgB;IAChB,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAChG,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,YAAY,GAAG,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;QACnC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,0BAA0B;IAC1B,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,IAAmB;IACzC,MAAM,CAAC,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,OAAO,CACL,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE;QACvC,CAAC,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,QAAQ,EAAE;QACjC,CAAC,CAAC,OAAO,EAAE,KAAK,KAAK,CAAC,OAAO,EAAE,CAChC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAmB;IAC3C,MAAM,CAAC,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,KAAK,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAmB,EAAE,IAAY;IAC5D,MAAM,CAAC,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.test.d.ts","sourceRoot":"","sources":["../../src/utils/date.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, test, expect } from "bun:test";
|
|
2
|
+
import { now, parseRelativeDate, formatDate, isToday, isPastDue, isWithinDays } from "./date.js";
|
|
3
|
+
describe("now", () => {
|
|
4
|
+
test("returns ISO timestamp string", () => {
|
|
5
|
+
const result = now();
|
|
6
|
+
expect(typeof result).toBe("string");
|
|
7
|
+
expect(result).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/);
|
|
8
|
+
});
|
|
9
|
+
test("returns current time within tolerance", () => {
|
|
10
|
+
const before = Date.now();
|
|
11
|
+
const result = now();
|
|
12
|
+
const after = Date.now();
|
|
13
|
+
const resultTime = new Date(result).getTime();
|
|
14
|
+
expect(resultTime).toBeGreaterThanOrEqual(before);
|
|
15
|
+
expect(resultTime).toBeLessThanOrEqual(after);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
describe("parseRelativeDate", () => {
|
|
19
|
+
test("parses 'today'", () => {
|
|
20
|
+
const result = parseRelativeDate("today");
|
|
21
|
+
expect(result).not.toBeNull();
|
|
22
|
+
const today = new Date();
|
|
23
|
+
expect(result.getDate()).toBe(today.getDate());
|
|
24
|
+
});
|
|
25
|
+
test("parses '오늘' (Korean today)", () => {
|
|
26
|
+
const result = parseRelativeDate("오늘");
|
|
27
|
+
expect(result).not.toBeNull();
|
|
28
|
+
const today = new Date();
|
|
29
|
+
expect(result.getDate()).toBe(today.getDate());
|
|
30
|
+
});
|
|
31
|
+
test("parses 'tomorrow'", () => {
|
|
32
|
+
const result = parseRelativeDate("tomorrow");
|
|
33
|
+
expect(result).not.toBeNull();
|
|
34
|
+
const tomorrow = new Date();
|
|
35
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
36
|
+
expect(result.getDate()).toBe(tomorrow.getDate());
|
|
37
|
+
});
|
|
38
|
+
test("parses '내일' (Korean tomorrow)", () => {
|
|
39
|
+
const result = parseRelativeDate("내일");
|
|
40
|
+
expect(result).not.toBeNull();
|
|
41
|
+
const tomorrow = new Date();
|
|
42
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
43
|
+
expect(result.getDate()).toBe(tomorrow.getDate());
|
|
44
|
+
});
|
|
45
|
+
test("parses 'yesterday'", () => {
|
|
46
|
+
const result = parseRelativeDate("yesterday");
|
|
47
|
+
expect(result).not.toBeNull();
|
|
48
|
+
const yesterday = new Date();
|
|
49
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
50
|
+
expect(result.getDate()).toBe(yesterday.getDate());
|
|
51
|
+
});
|
|
52
|
+
test("parses 'next week'", () => {
|
|
53
|
+
const result = parseRelativeDate("next week");
|
|
54
|
+
expect(result).not.toBeNull();
|
|
55
|
+
const nextWeek = new Date();
|
|
56
|
+
nextWeek.setDate(nextWeek.getDate() + 7);
|
|
57
|
+
expect(result.getDate()).toBe(nextWeek.getDate());
|
|
58
|
+
});
|
|
59
|
+
test("parses 'in 3 days'", () => {
|
|
60
|
+
const result = parseRelativeDate("in 3 days");
|
|
61
|
+
expect(result).not.toBeNull();
|
|
62
|
+
const future = new Date();
|
|
63
|
+
future.setDate(future.getDate() + 3);
|
|
64
|
+
expect(result.getDate()).toBe(future.getDate());
|
|
65
|
+
});
|
|
66
|
+
test("parses '5일 후' (Korean days later)", () => {
|
|
67
|
+
const result = parseRelativeDate("5일 후");
|
|
68
|
+
expect(result).not.toBeNull();
|
|
69
|
+
const future = new Date();
|
|
70
|
+
future.setDate(future.getDate() + 5);
|
|
71
|
+
expect(result.getDate()).toBe(future.getDate());
|
|
72
|
+
});
|
|
73
|
+
test("parses weekday names", () => {
|
|
74
|
+
const result = parseRelativeDate("monday");
|
|
75
|
+
expect(result).not.toBeNull();
|
|
76
|
+
expect(result.getDay()).toBe(1); // Monday = 1
|
|
77
|
+
});
|
|
78
|
+
test("parses ISO date string", () => {
|
|
79
|
+
const result = parseRelativeDate("2025-12-31");
|
|
80
|
+
expect(result).not.toBeNull();
|
|
81
|
+
expect(result.getFullYear()).toBe(2025);
|
|
82
|
+
expect(result.getMonth()).toBe(11); // December = 11
|
|
83
|
+
expect(result.getDate()).toBe(31);
|
|
84
|
+
});
|
|
85
|
+
test("returns null for invalid input", () => {
|
|
86
|
+
const result = parseRelativeDate("invalid date string");
|
|
87
|
+
expect(result).toBeNull();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe("formatDate", () => {
|
|
91
|
+
test("formats date as YYYY-MM-DD", () => {
|
|
92
|
+
const date = new Date("2025-06-15T10:30:00");
|
|
93
|
+
expect(formatDate(date)).toBe("2025-06-15");
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
describe("isToday", () => {
|
|
97
|
+
test("returns true for today", () => {
|
|
98
|
+
expect(isToday(new Date())).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
test("returns false for tomorrow", () => {
|
|
101
|
+
const tomorrow = new Date();
|
|
102
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
103
|
+
expect(isToday(tomorrow)).toBe(false);
|
|
104
|
+
});
|
|
105
|
+
test("accepts string input", () => {
|
|
106
|
+
expect(isToday(new Date().toISOString())).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("isPastDue", () => {
|
|
110
|
+
test("returns true for yesterday", () => {
|
|
111
|
+
const yesterday = new Date();
|
|
112
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
113
|
+
expect(isPastDue(yesterday)).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
test("returns false for tomorrow", () => {
|
|
116
|
+
const tomorrow = new Date();
|
|
117
|
+
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
118
|
+
expect(isPastDue(tomorrow)).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
describe("isWithinDays", () => {
|
|
122
|
+
test("returns true for date within range", () => {
|
|
123
|
+
const inThreeDays = new Date();
|
|
124
|
+
inThreeDays.setDate(inThreeDays.getDate() + 3);
|
|
125
|
+
expect(isWithinDays(inThreeDays, 7)).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
test("returns false for date outside range", () => {
|
|
128
|
+
const inTenDays = new Date();
|
|
129
|
+
inTenDays.setDate(inTenDays.getDate() + 10);
|
|
130
|
+
expect(isWithinDays(inTenDays, 7)).toBe(false);
|
|
131
|
+
});
|
|
132
|
+
test("returns false for past date", () => {
|
|
133
|
+
const yesterday = new Date();
|
|
134
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
135
|
+
expect(isWithinDays(yesterday, 7)).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=date.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date.test.js","sourceRoot":"","sources":["../../src/utils/date.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a unique ID with optional prefix
|
|
3
|
+
*/
|
|
4
|
+
export declare function generateId(prefix?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Generate a task ID
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateTaskId(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate a project ID
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateProjectId(): string;
|
|
13
|
+
/**
|
|
14
|
+
* Generate a view ID
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateViewId(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Validate a project ID format
|
|
19
|
+
* @returns true if valid format (proj_[alphanumeric])
|
|
20
|
+
*/
|
|
21
|
+
export declare function isValidProjectId(id: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Validate a task ID format
|
|
24
|
+
* @returns true if valid format (task_[alphanumeric])
|
|
25
|
+
*/
|
|
26
|
+
export declare function isValidTaskId(id: string): boolean;
|
|
27
|
+
//# sourceMappingURL=id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,GAAE,MAAW,GAAG,MAAM,CAItD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
package/dist/utils/id.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a unique ID with optional prefix
|
|
3
|
+
*/
|
|
4
|
+
export function generateId(prefix = "") {
|
|
5
|
+
const timestamp = Date.now().toString(36);
|
|
6
|
+
const random = Math.random().toString(36).substring(2, 8);
|
|
7
|
+
return prefix ? `${prefix}_${timestamp}${random}` : `${timestamp}${random}`;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a task ID
|
|
11
|
+
*/
|
|
12
|
+
export function generateTaskId() {
|
|
13
|
+
return generateId("task");
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generate a project ID
|
|
17
|
+
*/
|
|
18
|
+
export function generateProjectId() {
|
|
19
|
+
return generateId("proj");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generate a view ID
|
|
23
|
+
*/
|
|
24
|
+
export function generateViewId() {
|
|
25
|
+
return generateId("view");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate a project ID format
|
|
29
|
+
* @returns true if valid format (proj_[alphanumeric])
|
|
30
|
+
*/
|
|
31
|
+
export function isValidProjectId(id) {
|
|
32
|
+
return /^proj_[a-z0-9]+$/.test(id);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate a task ID format
|
|
36
|
+
* @returns true if valid format (task_[alphanumeric])
|
|
37
|
+
*/
|
|
38
|
+
export function isValidTaskId(id) {
|
|
39
|
+
return /^task_[a-z0-9]+$/.test(id);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,MAAM,EAAE,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,OAAO,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,OAAO,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { generateId, generateTaskId, generateProjectId, generateViewId, isValidProjectId, isValidTaskId } from "./id.js";
|
|
2
|
+
export { now, parseRelativeDate, formatDate, isToday, isPastDue, isWithinDays } from "./date.js";
|
|
3
|
+
export { parseTaskInput } from "./natural-language.js";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { generateId, generateTaskId, generateProjectId, generateViewId, isValidProjectId, isValidTaskId } from "./id.js";
|
|
2
|
+
export { now, parseRelativeDate, formatDate, isToday, isPastDue, isWithinDays } from "./date.js";
|
|
3
|
+
export { parseTaskInput } from "./natural-language.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzH,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TaskCreateInput } from "../schemas/task.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse natural language task input
|
|
4
|
+
*
|
|
5
|
+
* Examples:
|
|
6
|
+
* - "Review PR tomorrow #dev !high"
|
|
7
|
+
* - "내일까지 보고서 작성 #업무 !높음 @집중"
|
|
8
|
+
* - "Fix bug by Friday #backend !critical"
|
|
9
|
+
* - "Write tests every Monday #testing"
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseTaskInput(input: string): TaskCreateInput;
|
|
12
|
+
//# sourceMappingURL=natural-language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"natural-language.d.ts","sourceRoot":"","sources":["../../src/utils/natural-language.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGpE;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CA6F7D"}
|