things-api 0.7.0 → 0.9.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/README.md +6 -3
- package/dist/cli/commands/area.d.ts +23 -0
- package/dist/cli/commands/area.js +164 -33
- package/dist/cli/commands/area.js.map +1 -1
- package/dist/cli/commands/project.d.ts +19 -0
- package/dist/cli/commands/project.js +142 -29
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/reads.d.ts +10 -51
- package/dist/cli/commands/reads.js +454 -268
- package/dist/cli/commands/reads.js.map +1 -1
- package/dist/cli/commands/show.d.ts +9 -0
- package/dist/cli/commands/show.js +169 -0
- package/dist/cli/commands/show.js.map +1 -0
- package/dist/cli/commands/snapshot.js +1 -1
- package/dist/cli/commands/snapshot.js.map +1 -1
- package/dist/cli/commands/todo.d.ts +9 -0
- package/dist/cli/commands/todo.js +101 -16
- package/dist/cli/commands/todo.js.map +1 -1
- package/dist/cli/commands/writes.js +55 -1
- package/dist/cli/commands/writes.js.map +1 -1
- package/dist/cli/did-you-mean.d.ts +29 -0
- package/dist/cli/did-you-mean.js +53 -0
- package/dist/cli/did-you-mean.js.map +1 -0
- package/dist/cli/glyphs.d.ts +95 -0
- package/dist/cli/glyphs.js +282 -0
- package/dist/cli/glyphs.js.map +1 -0
- package/dist/cli/main.js +11 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/period.d.ts +32 -0
- package/dist/cli/period.js +129 -0
- package/dist/cli/period.js.map +1 -0
- package/dist/cli/read-driver.d.ts +76 -0
- package/dist/cli/read-driver.js +181 -0
- package/dist/cli/read-driver.js.map +1 -0
- package/dist/cli/render.d.ts +182 -0
- package/dist/cli/render.js +585 -0
- package/dist/cli/render.js.map +1 -0
- package/dist/cli/resolve-invocation.d.ts +78 -0
- package/dist/cli/resolve-invocation.js +178 -0
- package/dist/cli/resolve-invocation.js.map +1 -0
- package/dist/cli/shell-quote.d.ts +9 -0
- package/dist/cli/shell-quote.js +12 -0
- package/dist/cli/shell-quote.js.map +1 -0
- package/dist/cli/style.d.ts +5 -0
- package/dist/cli/style.js +5 -0
- package/dist/cli/style.js.map +1 -1
- package/dist/client.d.ts +45 -39
- package/dist/client.js +11 -74
- package/dist/client.js.map +1 -1
- package/dist/contracts.d.ts +66 -1
- package/dist/contracts.js +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/db/baselines/db-v26.js +7 -5
- package/dist/db/baselines/db-v26.js.map +1 -1
- package/dist/db/schema.d.ts +1 -1
- package/dist/db/schema.js +7 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/mcp/server.js +227 -44
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/entities.d.ts +21 -0
- package/dist/model/entities.js.map +1 -1
- package/dist/model/mappers.js +17 -1
- package/dist/model/mappers.js.map +1 -1
- package/dist/model/occurrences.d.ts +6 -1
- package/dist/model/occurrences.js +9 -2
- package/dist/model/occurrences.js.map +1 -1
- package/dist/model/recurrence.d.ts +30 -2
- package/dist/model/recurrence.js +20 -0
- package/dist/model/recurrence.js.map +1 -1
- package/dist/read/area-view.js +21 -5
- package/dist/read/area-view.js.map +1 -1
- package/dist/read/caps.d.ts +14 -0
- package/dist/read/caps.js +21 -0
- package/dist/read/caps.js.map +1 -0
- package/dist/read/detail.js +12 -2
- package/dist/read/detail.js.map +1 -1
- package/dist/read/log-boundary.d.ts +29 -0
- package/dist/read/log-boundary.js +38 -0
- package/dist/read/log-boundary.js.map +1 -0
- package/dist/read/pagination.d.ts +104 -0
- package/dist/read/pagination.js +208 -0
- package/dist/read/pagination.js.map +1 -0
- package/dist/read/predicates.d.ts +31 -0
- package/dist/read/predicates.js +48 -0
- package/dist/read/predicates.js.map +1 -0
- package/dist/read/project-view.js +28 -3
- package/dist/read/project-view.js.map +1 -1
- package/dist/read/queries.d.ts +21 -3
- package/dist/read/queries.js +35 -8
- package/dist/read/queries.js.map +1 -1
- package/dist/read/search-rank.d.ts +36 -0
- package/dist/read/search-rank.js +31 -0
- package/dist/read/search-rank.js.map +1 -0
- package/dist/read/show-target.d.ts +25 -0
- package/dist/read/show-target.js +41 -0
- package/dist/read/show-target.js.map +1 -0
- package/dist/read/sidebar-order.d.ts +19 -0
- package/dist/read/sidebar-order.js +92 -0
- package/dist/read/sidebar-order.js.map +1 -0
- package/dist/read/snapshot.js +2 -0
- package/dist/read/snapshot.js.map +1 -1
- package/dist/read/views.d.ts +64 -8
- package/dist/read/views.js +290 -155
- package/dist/read/views.js.map +1 -1
- package/dist/surface-copy.d.ts +23 -0
- package/dist/surface-copy.js +23 -0
- package/dist/surface-copy.js.map +1 -1
- package/dist/write/automation-probe.js +14 -6
- package/dist/write/automation-probe.js.map +1 -1
- package/dist/write/capabilities.d.ts +3 -0
- package/dist/write/capabilities.js +3 -0
- package/dist/write/capabilities.js.map +1 -1
- package/dist/write/checklist.d.ts +50 -0
- package/dist/write/checklist.js +61 -0
- package/dist/write/checklist.js.map +1 -0
- package/dist/write/clear-reminder.d.ts +3 -0
- package/dist/write/clear-reminder.js +205 -0
- package/dist/write/clear-reminder.js.map +1 -0
- package/dist/write/commands.js +122 -8
- package/dist/write/commands.js.map +1 -1
- package/dist/write/edit-checklist.d.ts +3 -0
- package/dist/write/edit-checklist.js +184 -0
- package/dist/write/edit-checklist.js.map +1 -0
- package/dist/write/failure-hints.d.ts +7 -0
- package/dist/write/failure-hints.js +25 -2
- package/dist/write/failure-hints.js.map +1 -1
- package/dist/write/guards.d.ts +1 -1
- package/dist/write/guards.js +16 -0
- package/dist/write/guards.js.map +1 -1
- package/dist/write/operations.d.ts +32 -1
- package/dist/write/operations.js +3 -0
- package/dist/write/operations.js.map +1 -1
- package/dist/write/pipeline.d.ts +3 -0
- package/dist/write/pipeline.js +23 -1
- package/dist/write/pipeline.js.map +1 -1
- package/dist/write/reversibility.d.ts +46 -0
- package/dist/write/reversibility.js +164 -0
- package/dist/write/reversibility.js.map +1 -0
- package/dist/write/undo.d.ts +29 -2
- package/dist/write/undo.js +357 -9
- package/dist/write/undo.js.map +1 -1
- package/dist/write/vectors/registry.js +2 -1
- package/dist/write/vectors/registry.js.map +1 -1
- package/dist/write/vectors/shortcuts.d.ts +9 -0
- package/dist/write/vectors/shortcuts.js +90 -0
- package/dist/write/vectors/shortcuts.js.map +1 -0
- package/dist/write/vectors/types.d.ts +11 -3
- package/dist/write/vectors/url-scheme.js +16 -0
- package/dist/write/vectors/url-scheme.js.map +1 -1
- package/dist/write/verify/delta.d.ts +1 -1
- package/dist/write/verify/delta.js +1 -1
- package/dist/write/verify/delta.js.map +1 -1
- package/package.json +1 -1
- package/shortcuts/things-proxy-find-items.shortcut +0 -0
package/dist/read/queries.d.ts
CHANGED
|
@@ -62,14 +62,32 @@ export interface NamedResolution {
|
|
|
62
62
|
* ambiguous; no tier is not-found. Shared by the read-side `resolve*Uuid`
|
|
63
63
|
* throwers and the write-side `resolve*` (ContainerResolution) helpers.
|
|
64
64
|
*/
|
|
65
|
-
export declare function resolveNamedRef(db: DatabaseSync, table: string, extraWhere: string, extraBinds: (string | number)[], refRaw: string
|
|
65
|
+
export declare function resolveNamedRef(db: DatabaseSync, table: string, extraWhere: string, extraBinds: (string | number)[], refRaw: string, options?: {
|
|
66
|
+
prefixTier?: boolean;
|
|
67
|
+
}): NamedResolution;
|
|
66
68
|
export declare function resolveTagUuid(db: DatabaseSync, ref: string): string;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Write destinations stay strict (a trashed project is not a valid target);
|
|
71
|
+
* READ surfaces pass `trashed: true` so a project in the Trash can still be
|
|
72
|
+
* viewed — its would-be-recovered children are only visible there.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveProjectUuid(db: DatabaseSync, ref: string, options?: {
|
|
75
|
+
trashed?: boolean;
|
|
76
|
+
prefixTier?: boolean;
|
|
77
|
+
}): string;
|
|
78
|
+
export declare function resolveAreaUuid(db: DatabaseSync, ref: string, options?: {
|
|
79
|
+
prefixTier?: boolean;
|
|
80
|
+
}): string;
|
|
69
81
|
export declare function fetchTaskRows(db: DatabaseSync, where: string, params?: unknown[]): TaskRow[];
|
|
70
82
|
export declare function fetchTaskByUuid(db: DatabaseSync, uuid: string): TaskRow | null;
|
|
71
83
|
export declare function fetchChecklistRows(db: DatabaseSync, taskUuid: string): ChecklistRow[];
|
|
72
84
|
/** Direct tags for a set of tasks, in one query. Returns uuid -> Ref[] (sorted by tag title). */
|
|
73
85
|
export declare function fetchTagsForTasks(db: DatabaseSync, taskUuids: string[]): Map<string, Ref[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Lazy heading-uuid -> owning-project Ref resolver, cached per instance.
|
|
88
|
+
* Heading-nested to-dos carry project = NULL in the DB (the heading holds
|
|
89
|
+
* the link); list views use this to surface the GUI's container label.
|
|
90
|
+
*/
|
|
91
|
+
export declare function makeHeadingProjectResolver(db: DatabaseSync): (headingUuid: string) => Ref | null;
|
|
74
92
|
/** Lazy uuid -> Ref resolver over TMTask + TMArea titles, cached per instance. */
|
|
75
93
|
export declare function makeRefResolver(db: DatabaseSync): (uuid: string | null) => Ref | null;
|
package/dist/read/queries.js
CHANGED
|
@@ -110,7 +110,7 @@ const BASE62 = /^[0-9A-Za-z]+$/;
|
|
|
110
110
|
* ambiguous; no tier is not-found. Shared by the read-side `resolve*Uuid`
|
|
111
111
|
* throwers and the write-side `resolve*` (ContainerResolution) helpers.
|
|
112
112
|
*/
|
|
113
|
-
export function resolveNamedRef(db, table, extraWhere, extraBinds, refRaw) {
|
|
113
|
+
export function resolveNamedRef(db, table, extraWhere, extraBinds, refRaw, options) {
|
|
114
114
|
const ref = stripThingsUri(refRaw);
|
|
115
115
|
const sel = (cond, extra = []) => db
|
|
116
116
|
.prepare(`SELECT uuid, title FROM ${table} WHERE ${extraWhere} AND ${cond}`)
|
|
@@ -133,7 +133,11 @@ export function resolveNamedRef(db, table, extraWhere, extraBinds, refRaw) {
|
|
|
133
133
|
if (hits.length > 1)
|
|
134
134
|
return { resolved: null, matches: hits.length };
|
|
135
135
|
}
|
|
136
|
-
|
|
136
|
+
// The uuid-prefix tier is suppressed on the sugar routing path (bare-noun /
|
|
137
|
+
// loose-show): there, a NAME subject resolves through exact/case/normalized
|
|
138
|
+
// only, and the did-you-mean substring fallback supersedes prefix guessing.
|
|
139
|
+
// Typed commands keep the historical tier.
|
|
140
|
+
if (options?.prefixTier !== false && ref.length >= 6 && BASE62.test(ref)) {
|
|
137
141
|
const upper = ref.slice(0, -1) + String.fromCharCode(ref.charCodeAt(ref.length - 1) + 1);
|
|
138
142
|
const rows = sel("uuid >= ? AND uuid < ?", [ref, upper]);
|
|
139
143
|
if (rows.length === 1)
|
|
@@ -143,8 +147,8 @@ export function resolveNamedRef(db, table, extraWhere, extraBinds, refRaw) {
|
|
|
143
147
|
}
|
|
144
148
|
return { resolved: null, matches: 0 };
|
|
145
149
|
}
|
|
146
|
-
function resolveUuidOrThrow(db, table, extraWhere, ref, kind, listCmd) {
|
|
147
|
-
const r = resolveNamedRef(db, table, extraWhere, [], ref);
|
|
150
|
+
function resolveUuidOrThrow(db, table, extraWhere, ref, kind, listCmd, options) {
|
|
151
|
+
const r = resolveNamedRef(db, table, extraWhere, [], ref, options);
|
|
148
152
|
if (r.resolved !== null)
|
|
149
153
|
return r.resolved.uuid;
|
|
150
154
|
throw new RangeError(r.matches === 0
|
|
@@ -154,11 +158,16 @@ function resolveUuidOrThrow(db, table, extraWhere, ref, kind, listCmd) {
|
|
|
154
158
|
export function resolveTagUuid(db, ref) {
|
|
155
159
|
return resolveUuidOrThrow(db, "TMTag", "1=1", ref, "tag", "things tags");
|
|
156
160
|
}
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Write destinations stay strict (a trashed project is not a valid target);
|
|
163
|
+
* READ surfaces pass `trashed: true` so a project in the Trash can still be
|
|
164
|
+
* viewed — its would-be-recovered children are only visible there.
|
|
165
|
+
*/
|
|
166
|
+
export function resolveProjectUuid(db, ref, options) {
|
|
167
|
+
return resolveUuidOrThrow(db, "TMTask", options?.trashed === true ? "type = 1" : "type = 1 AND trashed = 0", ref, "project", "things projects", options);
|
|
159
168
|
}
|
|
160
|
-
export function resolveAreaUuid(db, ref) {
|
|
161
|
-
return resolveUuidOrThrow(db, "TMArea", "1=1", ref, "area", "things areas");
|
|
169
|
+
export function resolveAreaUuid(db, ref, options) {
|
|
170
|
+
return resolveUuidOrThrow(db, "TMArea", "1=1", ref, "area", "things areas", options);
|
|
162
171
|
}
|
|
163
172
|
export function fetchTaskRows(db, where, params = []) {
|
|
164
173
|
const sql = `SELECT ${selectList("TMTask")
|
|
@@ -193,6 +202,24 @@ export function fetchTagsForTasks(db, taskUuids) {
|
|
|
193
202
|
}
|
|
194
203
|
return map;
|
|
195
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Lazy heading-uuid -> owning-project Ref resolver, cached per instance.
|
|
207
|
+
* Heading-nested to-dos carry project = NULL in the DB (the heading holds
|
|
208
|
+
* the link); list views use this to surface the GUI's container label.
|
|
209
|
+
*/
|
|
210
|
+
export function makeHeadingProjectResolver(db) {
|
|
211
|
+
const cache = new Map();
|
|
212
|
+
const stmt = db.prepare("SELECT p.uuid AS uuid, p.title AS title FROM TMTask h JOIN TMTask p ON p.uuid = h.project WHERE h.uuid = ?");
|
|
213
|
+
return (headingUuid) => {
|
|
214
|
+
const cached = cache.get(headingUuid);
|
|
215
|
+
if (cached !== undefined)
|
|
216
|
+
return cached;
|
|
217
|
+
const hit = stmt.get(headingUuid);
|
|
218
|
+
const ref = hit ? { uuid: hit.uuid, title: hit.title ?? "" } : null;
|
|
219
|
+
cache.set(headingUuid, ref);
|
|
220
|
+
return ref;
|
|
221
|
+
};
|
|
222
|
+
}
|
|
196
223
|
/** Lazy uuid -> Ref resolver over TMTask + TMArea titles, cached per instance. */
|
|
197
224
|
export function makeRefResolver(db) {
|
|
198
225
|
const cache = new Map();
|
package/dist/read/queries.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/read/queries.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/read/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The deterministic composite ranking for `things search` (docs/design/
|
|
3
|
+
* cli-grammar.md → search doctrine), replacing plain recency. A pure
|
|
4
|
+
* comparator so it is unit-testable in isolation and cannot drift from the
|
|
5
|
+
* documented order. Ranking runs BEFORE any row cap.
|
|
6
|
+
*
|
|
7
|
+
* Order (first differing key wins):
|
|
8
|
+
* 1. match field — title > notes > heading-via-project > checklist
|
|
9
|
+
* 2. type — projects/areas above to-dos
|
|
10
|
+
* 3. status — active above someday; logged/trashed last
|
|
11
|
+
* 4. tiebreak — most-recently-modified
|
|
12
|
+
*
|
|
13
|
+
* Consequence (deliberate): a someday TITLE match outranks an active NOTES
|
|
14
|
+
* match — field trumps status.
|
|
15
|
+
*/
|
|
16
|
+
import type { ListItem } from "./views.ts";
|
|
17
|
+
/** Which text carried the match. `heading` = a heading title, credited to its parent project. */
|
|
18
|
+
export type MatchField = "title" | "notes" | "heading" | "checklist";
|
|
19
|
+
export interface SearchMatch {
|
|
20
|
+
item: ListItem;
|
|
21
|
+
field: MatchField;
|
|
22
|
+
/** Present when `field === "heading"`: the heading whose title matched. */
|
|
23
|
+
matchedVia?: {
|
|
24
|
+
kind: "heading";
|
|
25
|
+
title: string;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare function fieldRank(field: MatchField): number;
|
|
29
|
+
/** Containers (projects, areas) sort above to-dos. */
|
|
30
|
+
export declare function typeRank(type: ListItem["type"] | "area"): number;
|
|
31
|
+
export type MatchStatus = "active" | "someday" | "logged" | "trashed";
|
|
32
|
+
/** Derive the ranking status bucket from an item's own state. */
|
|
33
|
+
export declare function matchStatus(item: ListItem): MatchStatus;
|
|
34
|
+
export declare function statusRank(status: MatchStatus): number;
|
|
35
|
+
/** The composite comparator. Stable and total: ties fall through to the uuid. */
|
|
36
|
+
export declare function compareSearchMatches(a: SearchMatch, b: SearchMatch): number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const FIELD_ORDER = { title: 0, notes: 1, heading: 2, checklist: 3 };
|
|
2
|
+
export function fieldRank(field) {
|
|
3
|
+
return FIELD_ORDER[field];
|
|
4
|
+
}
|
|
5
|
+
/** Containers (projects, areas) sort above to-dos. */
|
|
6
|
+
export function typeRank(type) {
|
|
7
|
+
return type === "to-do" ? 1 : 0;
|
|
8
|
+
}
|
|
9
|
+
/** Derive the ranking status bucket from an item's own state. */
|
|
10
|
+
export function matchStatus(item) {
|
|
11
|
+
if (item.trashed)
|
|
12
|
+
return "trashed";
|
|
13
|
+
if (item.status !== "open")
|
|
14
|
+
return "logged";
|
|
15
|
+
if (item.start === "someday")
|
|
16
|
+
return "someday";
|
|
17
|
+
return "active";
|
|
18
|
+
}
|
|
19
|
+
const STATUS_ORDER = { active: 0, someday: 1, logged: 2, trashed: 3 };
|
|
20
|
+
export function statusRank(status) {
|
|
21
|
+
return STATUS_ORDER[status];
|
|
22
|
+
}
|
|
23
|
+
/** The composite comparator. Stable and total: ties fall through to the uuid. */
|
|
24
|
+
export function compareSearchMatches(a, b) {
|
|
25
|
+
return (fieldRank(a.field) - fieldRank(b.field) ||
|
|
26
|
+
typeRank(a.item.type) - typeRank(b.item.type) ||
|
|
27
|
+
statusRank(matchStatus(a.item)) - statusRank(matchStatus(b.item)) ||
|
|
28
|
+
b.item.modified.getTime() - a.item.modified.getTime() ||
|
|
29
|
+
a.item.uuid.localeCompare(b.item.uuid));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=search-rank.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-rank.js","sourceRoot":"","sources":["../../src/read/search-rank.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,GAA+B,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAEjG,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,QAAQ,CAAC,IAA+B;IACtD,OAAO,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClC,CAAC;AAID,iEAAiE;AACjE,MAAM,UAAU,WAAW,CAAC,IAAc;IACxC,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC/C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,YAAY,GAAgC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAEnG,MAAM,UAAU,UAAU,CAAC,MAAmB;IAC5C,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,oBAAoB,CAAC,CAAc,EAAE,CAAc;IACjE,OAAO,CACL,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;QACvC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7C,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;QACrD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACvC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loose reference classification for `things show` / the `open` commands:
|
|
3
|
+
* anything a user might copy — a full uuid, a >=6-char uuid prefix, a
|
|
4
|
+
* things:/// share link, or a unique area/project name — resolves to the
|
|
5
|
+
* resource class that has a show view (an area wins over a same-named
|
|
6
|
+
* project). Headings resolve to their CONTAINING PROJECT (they have no view
|
|
7
|
+
* of their own); tags and checklist items are rejected (no show view; their
|
|
8
|
+
* uuids simply never match TMTask/TMArea).
|
|
9
|
+
*
|
|
10
|
+
* NAME resolution on this loose/sugar path is deliberately narrower than the
|
|
11
|
+
* typed commands' (docs/design/cli-grammar.md): only AREAS and PROJECTS
|
|
12
|
+
* resolve by name (to-do TITLES never route here — a to-do is reachable only
|
|
13
|
+
* by uuid/prefix/share-link, or from the did-you-mean list), and the
|
|
14
|
+
* uuid-PREFIX tier is dropped (`prefixTier: false`) so the did-you-mean
|
|
15
|
+
* substring fallback supersedes prefix guessing. Task uuid prefixes still
|
|
16
|
+
* resolve up front via {@link resolveTaskUuidPrefix}.
|
|
17
|
+
*/
|
|
18
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
19
|
+
export interface ShowTarget {
|
|
20
|
+
kind: "to-do" | "project" | "area";
|
|
21
|
+
uuid: string;
|
|
22
|
+
/** True when the ref was a HEADING resolved to its project — strict noun commands reject these. */
|
|
23
|
+
viaHeading?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare function classifyShowTarget(db: DatabaseSync, ref: string): ShowTarget;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { resolveAreaUuid, resolveProjectUuid, resolveTaskUuidPrefix, stripThingsUri, } from "./queries.js";
|
|
2
|
+
export function classifyShowTarget(db, ref) {
|
|
3
|
+
const stripped = stripThingsUri(ref);
|
|
4
|
+
try {
|
|
5
|
+
const uuid = resolveTaskUuidPrefix(db, stripped);
|
|
6
|
+
const row = db.prepare("SELECT type, project FROM TMTask WHERE uuid = ?").get(uuid);
|
|
7
|
+
if (row.type === 1)
|
|
8
|
+
return { kind: "project", uuid };
|
|
9
|
+
if (row.type === 2) {
|
|
10
|
+
if (row.project === null)
|
|
11
|
+
throw new RangeError(`heading ${uuid} has no containing project to show`);
|
|
12
|
+
return { kind: "project", uuid: row.project, viaHeading: true };
|
|
13
|
+
}
|
|
14
|
+
return { kind: "to-do", uuid };
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
// An ambiguous prefix lists its candidates — surface that verbatim.
|
|
18
|
+
// Plain not-found (or a too-short ref, e.g. an area name like "Home")
|
|
19
|
+
// falls through to area resolution.
|
|
20
|
+
if (err instanceof RangeError && err.message.includes("ambiguous"))
|
|
21
|
+
throw err;
|
|
22
|
+
if (!(err instanceof RangeError))
|
|
23
|
+
throw err;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return { kind: "area", uuid: resolveAreaUuid(db, stripped, { prefixTier: false }) };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// fall through to project-name resolution
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return { kind: "project", uuid: resolveProjectUuid(db, stripped, { prefixTier: false }) };
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
// An ambiguous project name lists its candidates — surface that verbatim.
|
|
36
|
+
if (err instanceof RangeError && err.message.includes("ambiguous"))
|
|
37
|
+
throw err;
|
|
38
|
+
throw new RangeError(`no to-do, project, or area matches "${ref}" (tags and checklist items have no show view)`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=show-target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show-target.js","sourceRoot":"","sources":["../../src/read/show-target.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,GACf,MAAM,cAAc,CAAC;AAStB,MAAM,UAAU,kBAAkB,CAAC,EAAgB,EAAE,GAAW;IAC9D,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,qBAAqB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAAC,IAAI,CAGjF,CAAC;QACF,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QACrD,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACnB,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI;gBACtB,MAAM,IAAI,UAAU,CAAC,WAAW,IAAI,oCAAoC,CAAC,CAAC;YAC5E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAClE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,oEAAoE;QACpE,sEAAsE;QACtE,oCAAoC;QACpC,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,MAAM,GAAG,CAAC;QAC9E,IAAI,CAAC,CAAC,GAAG,YAAY,UAAU,CAAC;YAAE,MAAM,GAAG,CAAC;IAC9C,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAC5F,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YAAE,MAAM,GAAG,CAAC;QAC9E,MAAM,IAAI,UAAU,CAClB,uCAAuC,GAAG,gDAAgD,CAC3F,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sidebar-order arrangement for the grouped views (anytime/someday). Takes an
|
|
3
|
+
* already-materialized flat list and reproduces the UI's sidebar layout:
|
|
4
|
+
* the area-less block first, then each area by its sidebar index; inside a
|
|
5
|
+
* block, direct to-dos first, then each project followed by its members.
|
|
6
|
+
*
|
|
7
|
+
* Type-only imports from views.ts (ListItem, SidebarSection) are erased at
|
|
8
|
+
* runtime, so the sole runtime edge is views.ts → sidebar-order.ts.
|
|
9
|
+
*/
|
|
10
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
11
|
+
import type { ListItem, SidebarSection } from "./views.ts";
|
|
12
|
+
/**
|
|
13
|
+
* Arranges view members into the UI's flat sidebar-mirroring order: the
|
|
14
|
+
* area-less block first (direct to-dos, then each top-level project followed
|
|
15
|
+
* by its members), then each area by its sidebar index (direct to-dos, then
|
|
16
|
+
* its projects). Project and area order here mirrors the sidebar exactly —
|
|
17
|
+
* both read the same "index" columns.
|
|
18
|
+
*/
|
|
19
|
+
export declare function groupBySidebar(db: DatabaseSync, items: ListItem[]): SidebarSection[];
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arranges view members into the UI's flat sidebar-mirroring order: the
|
|
3
|
+
* area-less block first (direct to-dos, then each top-level project followed
|
|
4
|
+
* by its members), then each area by its sidebar index (direct to-dos, then
|
|
5
|
+
* its projects). Project and area order here mirrors the sidebar exactly —
|
|
6
|
+
* both read the same "index" columns.
|
|
7
|
+
*/
|
|
8
|
+
export function groupBySidebar(db, items) {
|
|
9
|
+
if (items.length === 0)
|
|
10
|
+
return [];
|
|
11
|
+
const inList = (n) => Array.from({ length: n }, () => "?").join(", ");
|
|
12
|
+
// Headed children: resolve heading -> project.
|
|
13
|
+
const headingUuids = [
|
|
14
|
+
...new Set(items.flatMap((i) => (i.type === "to-do" && i.heading !== null ? [i.heading.uuid] : []))),
|
|
15
|
+
];
|
|
16
|
+
const headingProject = new Map();
|
|
17
|
+
if (headingUuids.length > 0) {
|
|
18
|
+
for (const row of db
|
|
19
|
+
.prepare(`SELECT uuid, project FROM TMTask WHERE uuid IN (${inList(headingUuids.length)})`)
|
|
20
|
+
.all(...headingUuids)) {
|
|
21
|
+
headingProject.set(row.uuid, row.project);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const effProject = (i) => i.type !== "to-do"
|
|
25
|
+
? null
|
|
26
|
+
: (i.project?.uuid ??
|
|
27
|
+
(i.heading !== null ? (headingProject.get(i.heading.uuid) ?? null) : null));
|
|
28
|
+
// Sidebar rank + title for areas; index + area for every referenced project
|
|
29
|
+
// (a tag-filtered list can contain a child whose project row didn't match).
|
|
30
|
+
const areaRows = db
|
|
31
|
+
.prepare(`SELECT uuid, title, "index" FROM TMArea ORDER BY "index" ASC, uuid ASC`)
|
|
32
|
+
.all();
|
|
33
|
+
const areaRank = new Map(areaRows.map((a, rank) => [a.uuid, rank]));
|
|
34
|
+
const areaTitle = new Map(areaRows.map((a) => [a.uuid, a.title ?? ""]));
|
|
35
|
+
const projectUuids = [
|
|
36
|
+
...new Set([
|
|
37
|
+
...items.flatMap((i) => (i.type === "project" ? [i.uuid] : [])),
|
|
38
|
+
...items.flatMap((i) => {
|
|
39
|
+
const p = effProject(i);
|
|
40
|
+
return p === null ? [] : [p];
|
|
41
|
+
}),
|
|
42
|
+
]),
|
|
43
|
+
];
|
|
44
|
+
const projectMeta = new Map();
|
|
45
|
+
if (projectUuids.length > 0) {
|
|
46
|
+
for (const row of db
|
|
47
|
+
.prepare(`SELECT uuid, "index", area FROM TMTask WHERE uuid IN (${inList(projectUuids.length)})`)
|
|
48
|
+
.all(...projectUuids)) {
|
|
49
|
+
projectMeta.set(row.uuid, { index: row.index ?? 0, area: row.area });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// items arrive in SQL "index" order, so array position IS the per-container
|
|
53
|
+
// rank (the internal index is no longer exposed on the entity).
|
|
54
|
+
const sortKey = (i, pos) => {
|
|
55
|
+
const project = i.type === "project" ? i.uuid : effProject(i);
|
|
56
|
+
const meta = project === null ? undefined : projectMeta.get(project);
|
|
57
|
+
const area = i.area?.uuid ?? meta?.area ?? null;
|
|
58
|
+
return {
|
|
59
|
+
areaRank: area === null ? -1 : (areaRank.get(area) ?? areaRows.length),
|
|
60
|
+
area: area ?? "",
|
|
61
|
+
inProject: project === null ? 0 : 1,
|
|
62
|
+
projectIndex: meta?.index ?? 0,
|
|
63
|
+
project: project ?? "",
|
|
64
|
+
headerFirst: i.type === "project" ? 0 : 1,
|
|
65
|
+
pos,
|
|
66
|
+
uuid: i.uuid,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
const keyed = items.map((item, pos) => ({ item, k: sortKey(item, pos) }));
|
|
70
|
+
keyed.sort((a, b) => a.k.areaRank - b.k.areaRank ||
|
|
71
|
+
a.k.area.localeCompare(b.k.area) ||
|
|
72
|
+
a.k.inProject - b.k.inProject ||
|
|
73
|
+
a.k.projectIndex - b.k.projectIndex ||
|
|
74
|
+
a.k.project.localeCompare(b.k.project) ||
|
|
75
|
+
a.k.headerFirst - b.k.headerFirst ||
|
|
76
|
+
a.k.pos - b.k.pos ||
|
|
77
|
+
a.k.uuid.localeCompare(b.k.uuid));
|
|
78
|
+
const sections = [];
|
|
79
|
+
for (const { item, k } of keyed) {
|
|
80
|
+
const areaUuid = k.area === "" ? null : k.area;
|
|
81
|
+
const last = sections.at(-1);
|
|
82
|
+
if (last === undefined || (last.area?.uuid ?? null) !== areaUuid) {
|
|
83
|
+
sections.push({
|
|
84
|
+
area: areaUuid === null ? null : { uuid: areaUuid, title: areaTitle.get(areaUuid) ?? "" },
|
|
85
|
+
items: [],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
sections.at(-1)?.items.push(item);
|
|
89
|
+
}
|
|
90
|
+
return sections;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=sidebar-order.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-order.js","sourceRoot":"","sources":["../../src/read/sidebar-order.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,EAAgB,EAAE,KAAiB;IAChE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE9E,+CAA+C;IAC/C,MAAM,YAAY,GAAG;QACnB,GAAG,IAAI,GAAG,CACR,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACzF;KACF,CAAC;IACF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyB,CAAC;IACxD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,EAAE;aACjB,OAAO,CAAC,mDAAmD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1F,GAAG,CAAC,GAAG,YAAY,CAAoD,EAAE,CAAC;YAC3E,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,CAAW,EAAiB,EAAE,CAChD,CAAC,CAAC,IAAI,KAAK,OAAO;QAChB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI;YAChB,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAElF,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,QAAQ,GAAG,EAAE;SAChB,OAAO,CAAC,wEAAwE,CAAC;SACjF,GAAG,EAAmD,CAAC;IAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG;QACnB,GAAG,IAAI,GAAG,CAAC;YACT,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC/D,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBACrB,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBACxB,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC,CAAC;SACH,CAAC;KACH,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkD,CAAC;IAC9E,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,GAAG,IAAI,EAAE;aACjB,OAAO,CACN,yDAAyD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CACxF;aACA,GAAG,CAAC,GAAG,YAAY,CAAuE,EAAE,CAAC;YAC9F,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,gEAAgE;IAChE,MAAM,OAAO,GAAG,CAAC,CAAW,EAAE,GAAW,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;QAChD,OAAO;YACL,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC;YACtE,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,YAAY,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;YAC9B,OAAO,EAAE,OAAO,IAAI,EAAE;YACtB,WAAW,EAAE,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzC,GAAG;YACH,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CACR,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ;QAC3B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAC7B,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY;QACnC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACtC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW;QACjC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;QACjB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CACnC,CAAC;IAEF,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjE,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE;gBACzF,KAAK,EAAE,EAAE;aACV,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/read/snapshot.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { q, selectList } from "../db/schema.js";
|
|
2
2
|
import { mapChecklistItem, mapHeading, mapProject, mapTodo, } from "../model/mappers.js";
|
|
3
3
|
import { fetchTagsForTasks, fetchTaskRows, makeRefResolver } from "./queries.js";
|
|
4
|
+
import { logBoundary, markLogged } from "./log-boundary.js";
|
|
4
5
|
import { areasView, tagsView } from "./tags.js";
|
|
5
6
|
export function snapshotView(db) {
|
|
6
7
|
const areas = areasView(db);
|
|
@@ -14,6 +15,7 @@ export function snapshotView(db) {
|
|
|
14
15
|
const rowTags = tagMap.get(row.uuid) ?? [];
|
|
15
16
|
return row.type === 1 ? mapProject(row, refs, rowTags) : mapTodo(row, refs, rowTags);
|
|
16
17
|
});
|
|
18
|
+
markLogged(tasks.filter((t) => t.type !== "heading"), logBoundary(db));
|
|
17
19
|
const checklistRows = db
|
|
18
20
|
.prepare(`SELECT ${selectList("TMChecklistItem")} FROM TMChecklistItem ORDER BY ${q("uuid")} ASC`)
|
|
19
21
|
.all();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/read/snapshot.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,OAAO,GAER,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAmBhD,MAAM,UAAU,YAAY,CAAC,EAAgB;IAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,aAAa,CAAC,EAAE,EAAE,yBAAyB,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,iBAAiB,CAC9B,EAAE,EACF,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACxB,CAAC;IACF,MAAM,KAAK,GAAc,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACxC,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,EAAE;SACrB,OAAO,CACN,UAAU,UAAU,CAAC,iBAAiB,CAAC,kCAAkC,CAAC,CAAC,MAAM,CAAC,MAAM,CACzF;SACA,GAAG,EAA+B,CAAC;IACtC,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAE3D,OAAO;QACL,KAAK;QACL,IAAI;QACJ,KAAK;QACL,cAAc;QACd,MAAM,EAAE;YACN,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM;YAC9C,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM;YACjD,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM;YACjD,cAAc,EAAE,cAAc,CAAC,MAAM;YACrC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM;YACnD,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC;iBACzF,MAAM;SACV;KACF,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/read/snapshot.ts"],"names":[],"mappings":"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"}
|
package/dist/read/views.d.ts
CHANGED
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
* untrashed (unless trash), repeating TEMPLATE rows excluded.
|
|
47
47
|
*/
|
|
48
48
|
import type { DatabaseSync } from "node:sqlite";
|
|
49
|
+
import { type IsoDate } from "../model/dates.ts";
|
|
49
50
|
import type { Project, Ref, Todo } from "../model/entities.ts";
|
|
51
|
+
import type { Area } from "../model/entities.ts";
|
|
50
52
|
export type ListItem = Todo | Project;
|
|
51
53
|
/** Optional list-view filters. */
|
|
52
54
|
export interface ViewFilter {
|
|
@@ -97,6 +99,19 @@ export interface UpcomingFilter extends ViewFilter {
|
|
|
97
99
|
* 10) — projections are host math the app has not materialized yet.
|
|
98
100
|
*/
|
|
99
101
|
horizon?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Only rows scheduled on/before this date (inclusive). Dated rows and
|
|
104
|
+
* template occurrences beyond it are dropped; the dateless resting
|
|
105
|
+
* templates (the trailing Repeating To-Dos section) always survive —
|
|
106
|
+
* a date bound cannot apply to rows with no date.
|
|
107
|
+
*/
|
|
108
|
+
until?: IsoDate;
|
|
109
|
+
/**
|
|
110
|
+
* Only rows scheduled on/after this date (inclusive) — skip occurrences
|
|
111
|
+
* before it. The dateless resting templates always survive, as with
|
|
112
|
+
* `until` (a date bound cannot apply to rows with no date).
|
|
113
|
+
*/
|
|
114
|
+
since?: IsoDate;
|
|
100
115
|
}
|
|
101
116
|
export declare function upcomingView(db: DatabaseSync, now?: Date, filter?: UpcomingFilter): ListItem[];
|
|
102
117
|
export interface SomedayFilter extends ViewFilter {
|
|
@@ -109,18 +124,34 @@ export interface SomedayFilter extends ViewFilter {
|
|
|
109
124
|
activeProjectItems?: boolean;
|
|
110
125
|
}
|
|
111
126
|
export declare function somedayView(db: DatabaseSync, now?: Date, filter?: SomedayFilter): SidebarSection[];
|
|
112
|
-
export
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
127
|
+
export interface LogbookFilter extends ViewFilter {
|
|
128
|
+
/** Row cap; `null` returns every match (surfaces slice for display). */
|
|
129
|
+
limit?: number | null;
|
|
130
|
+
/**
|
|
131
|
+
* Area scope: the area's direct items, its project rows, and every to-do
|
|
132
|
+
* of its projects — INCLUDING heading-nested ones (heading → project →
|
|
133
|
+
* area). Uuid or unique name.
|
|
134
|
+
*/
|
|
135
|
+
area?: string;
|
|
136
|
+
/** Project scope: ALL children, heading-nested included. Uuid or unique name. */
|
|
137
|
+
project?: string;
|
|
138
|
+
/** Only entries logged at/after this instant. */
|
|
139
|
+
since?: Date;
|
|
140
|
+
/** Only entries logged at/before this instant. */
|
|
141
|
+
until?: Date;
|
|
142
|
+
}
|
|
143
|
+
export declare function logbookView(db: DatabaseSync, options?: LogbookFilter): ListItem[];
|
|
116
144
|
export declare function trashView(db: DatabaseSync, options?: {
|
|
117
|
-
limit?: number;
|
|
145
|
+
limit?: number | null;
|
|
118
146
|
}): ListItem[];
|
|
119
147
|
export declare function projectsView(db: DatabaseSync, options?: {
|
|
120
148
|
areaUuid?: string;
|
|
149
|
+
later?: boolean;
|
|
150
|
+
now?: Date;
|
|
121
151
|
}): Project[];
|
|
122
152
|
export interface SearchOptions extends ViewFilter {
|
|
123
|
-
|
|
153
|
+
/** Row cap; `null` returns every match (surfaces slice for display). */
|
|
154
|
+
limit?: number | null;
|
|
124
155
|
/** Restrict to one project's children (headed children included). */
|
|
125
156
|
project?: string;
|
|
126
157
|
/** Restrict to one area's direct members. */
|
|
@@ -147,6 +178,31 @@ export type ChangedItem = ListItem & {
|
|
|
147
178
|
*/
|
|
148
179
|
export declare function changesView(db: DatabaseSync, options: {
|
|
149
180
|
since: Date;
|
|
150
|
-
limit?: number;
|
|
181
|
+
limit?: number | null;
|
|
151
182
|
}): ChangedItem[];
|
|
152
|
-
|
|
183
|
+
/** One did-you-mean candidate: an area, or a task (project / to-do). */
|
|
184
|
+
export type LiteCandidate = {
|
|
185
|
+
kind: "area";
|
|
186
|
+
area: Area;
|
|
187
|
+
} | {
|
|
188
|
+
kind: "task";
|
|
189
|
+
task: ListItem;
|
|
190
|
+
};
|
|
191
|
+
export interface LiteSearchResult {
|
|
192
|
+
/** Ordered (containers first, then to-dos; within a group: active before someday, then most-recently-modified) and capped. */
|
|
193
|
+
candidates: LiteCandidate[];
|
|
194
|
+
/** Total matches before the cap. */
|
|
195
|
+
total: number;
|
|
196
|
+
}
|
|
197
|
+
export declare function liteTitleSearch(db: DatabaseSync, query: string, options?: {
|
|
198
|
+
type?: "to-do" | "project" | "area";
|
|
199
|
+
limit?: number;
|
|
200
|
+
}): LiteSearchResult;
|
|
201
|
+
/** A search result annotated with WHY it surfaced (additive; `matchedVia` present only for heading-credited projects). */
|
|
202
|
+
export type SearchResultItem = ListItem & {
|
|
203
|
+
matchedVia?: {
|
|
204
|
+
kind: "heading";
|
|
205
|
+
title: string;
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
export declare function searchView(db: DatabaseSync, query: string, options?: SearchOptions): SearchResultItem[];
|