draftlink 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/src/assets.ts ADDED
@@ -0,0 +1,4 @@
1
+ // Draftlink logo + favicon, generated from assets/logo source art.
2
+ // Regenerate: resize assets to 160px / 48px PNG and re-embed base64.
3
+ export const LOGO_PNG = "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";
4
+ export const FAVICON_PNG = "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";
package/src/drafts.ts ADDED
@@ -0,0 +1,209 @@
1
+ import { randomId } from "./util";
2
+
3
+ export const STATUS_ORDER = ["active", "done", "archived"] as const;
4
+ export type Status = (typeof STATUS_ORDER)[number];
5
+
6
+ // Keep the last 25 versions per draft; raise if agent churn overflows this.
7
+ const VERSIONS_KEPT = 25;
8
+
9
+ export interface VersionRow {
10
+ id: number;
11
+ created_at: number;
12
+ }
13
+
14
+ export interface DraftRow {
15
+ id: string;
16
+ title: string;
17
+ project: string;
18
+ status: string;
19
+ is_public: number;
20
+ created_at: number;
21
+ updated_at: number;
22
+ owner_login?: string;
23
+ }
24
+
25
+ export interface DraftFullRow extends DraftRow {
26
+ owner_user_id: number;
27
+ body: string;
28
+ }
29
+
30
+ export type Access = { draft: DraftFullRow; isOwner: boolean; canEdit: boolean };
31
+
32
+ export type Viewer = { id: number; github_id: number } | null;
33
+
34
+ export function validStatus(s: string | null | undefined): Status {
35
+ return STATUS_ORDER.includes(s as Status) ? (s as Status) : "active";
36
+ }
37
+
38
+ function likePattern(q: string): string {
39
+ return `%${q.replace(/[\\%_]/g, (m) => `\\${m}`)}%`;
40
+ }
41
+
42
+ export async function resolveAccess(db: D1Database, id: string, viewer: Viewer): Promise<Access | null> {
43
+ const draft = await db
44
+ .prepare("SELECT d.*, u.login AS owner_login FROM drafts d JOIN users u ON u.id = d.owner_user_id WHERE d.id = ?")
45
+ .bind(id)
46
+ .first<DraftFullRow & { owner_login: string }>();
47
+ if (!draft) return null;
48
+ const isOwner = !!viewer && viewer.id === draft.owner_user_id;
49
+ let canEdit = isOwner;
50
+ if (!canEdit && viewer) {
51
+ const g = await db.prepare("SELECT 1 AS x FROM draft_access WHERE draft_id = ? AND github_id = ?").bind(id, viewer.github_id).first();
52
+ canEdit = !!g;
53
+ }
54
+ return { draft, isOwner, canEdit };
55
+ }
56
+
57
+ export function canRead(a: Access): boolean {
58
+ return a.draft.is_public === 1 || a.canEdit;
59
+ }
60
+
61
+ function versionStatements(db: D1Database, draftId: string, body: string, now: number): D1PreparedStatement[] {
62
+ return [
63
+ db.prepare("INSERT INTO draft_versions (draft_id, body, created_at) VALUES (?, ?, ?)").bind(draftId, body, now),
64
+ db
65
+ .prepare(
66
+ "DELETE FROM draft_versions WHERE draft_id = ? AND id NOT IN (SELECT id FROM draft_versions WHERE draft_id = ? ORDER BY created_at DESC, id DESC LIMIT ?)"
67
+ )
68
+ .bind(draftId, draftId, VERSIONS_KEPT),
69
+ ];
70
+ }
71
+
72
+ export async function listVersions(db: D1Database, draftId: string): Promise<VersionRow[]> {
73
+ const { results } = await db
74
+ .prepare("SELECT id, created_at FROM draft_versions WHERE draft_id = ? ORDER BY created_at DESC, id DESC")
75
+ .bind(draftId)
76
+ .all<VersionRow>();
77
+ return results ?? [];
78
+ }
79
+
80
+ export async function getVersion(db: D1Database, draftId: string, versionId: number): Promise<{ id: number; body: string; created_at: number } | null> {
81
+ return await db
82
+ .prepare("SELECT id, body, created_at FROM draft_versions WHERE id = ? AND draft_id = ?")
83
+ .bind(versionId, draftId)
84
+ .first<{ id: number; body: string; created_at: number }>();
85
+ }
86
+
87
+ export async function create(
88
+ db: D1Database,
89
+ ownerUserId: number,
90
+ input: { title?: string; project?: string; status?: Status; body: string }
91
+ ): Promise<string> {
92
+ const id = randomId(12);
93
+ const now = Date.now();
94
+ await db
95
+ .prepare("INSERT INTO drafts (id, owner_user_id, title, project, status, body, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
96
+ .bind(id, ownerUserId, (input.title ?? "untitled").slice(0, 300), (input.project ?? "misc").slice(0, 100), input.status ?? "active", input.body, now, now)
97
+ .run();
98
+ return id;
99
+ }
100
+
101
+ export interface UpdateInput {
102
+ title?: string;
103
+ project?: string;
104
+ status?: Status;
105
+ isPublic?: number;
106
+ body?: string;
107
+ }
108
+
109
+ export async function update(db: D1Database, id: string, input: UpdateInput): Promise<void> {
110
+ let previous: string | undefined;
111
+ if (input.body !== undefined) {
112
+ const cur = await db.prepare("SELECT body FROM drafts WHERE id = ?").bind(id).first<{ body: string }>();
113
+ previous = cur?.body;
114
+ }
115
+ const sets = ["updated_at = ?"];
116
+ const args: unknown[] = [Date.now()];
117
+ if (input.title !== undefined) {
118
+ sets.push("title = ?");
119
+ args.push(input.title.slice(0, 300));
120
+ }
121
+ if (input.project !== undefined) {
122
+ sets.push("project = ?");
123
+ args.push(input.project.slice(0, 100));
124
+ }
125
+ if (input.status !== undefined) {
126
+ sets.push("status = ?");
127
+ args.push(input.status);
128
+ }
129
+ if (input.isPublic !== undefined) {
130
+ sets.push("is_public = ?");
131
+ args.push(input.isPublic);
132
+ }
133
+ if (input.body !== undefined) {
134
+ sets.push("body = ?");
135
+ args.push(input.body);
136
+ }
137
+ args.push(id);
138
+ const statements = [db.prepare(`UPDATE drafts SET ${sets.join(", ")} WHERE id = ?`).bind(...args)];
139
+ if (previous !== undefined && previous !== input.body) statements.push(...versionStatements(db, id, previous, Date.now()));
140
+ await db.batch(statements);
141
+ }
142
+
143
+ export async function remove(db: D1Database, id: string): Promise<void> {
144
+ await db.batch([
145
+ db.prepare("DELETE FROM draft_access WHERE draft_id = ?").bind(id),
146
+ db.prepare("DELETE FROM draft_versions WHERE draft_id = ?").bind(id),
147
+ db.prepare("DELETE FROM drafts WHERE id = ?").bind(id),
148
+ ]);
149
+ }
150
+
151
+ export async function grant(db: D1Database, draftId: string, resolved: { github_id: number; login: string }): Promise<void> {
152
+ await db
153
+ .prepare("INSERT INTO draft_access (draft_id, github_id, login, created_at) VALUES (?, ?, ?, ?) ON CONFLICT(draft_id, github_id) DO NOTHING")
154
+ .bind(draftId, resolved.github_id, resolved.login, Date.now())
155
+ .run();
156
+ }
157
+
158
+ export async function revoke(db: D1Database, draftId: string, githubId: number): Promise<void> {
159
+ await db.prepare("DELETE FROM draft_access WHERE draft_id = ? AND github_id = ?").bind(draftId, githubId).run();
160
+ }
161
+
162
+ export async function listGrants(db: D1Database, draftId: string): Promise<{ github_id: number; login: string }[]> {
163
+ const { results } = await db
164
+ .prepare("SELECT github_id, login FROM draft_access WHERE draft_id = ? ORDER BY created_at")
165
+ .bind(draftId)
166
+ .all<{ github_id: number; login: string }>();
167
+ return results ?? [];
168
+ }
169
+
170
+ export async function listMine(db: D1Database, userId: number, q: string, filter: string, project: string): Promise<DraftRow[]> {
171
+ const like = likePattern(q);
172
+ const { results } = await db
173
+ .prepare(
174
+ `SELECT id, title, project, status, is_public, created_at, updated_at FROM drafts
175
+ WHERE owner_user_id = ?1 AND (?2 = '%%' OR title LIKE ?2 ESCAPE '\\' OR project LIKE ?2 ESCAPE '\\' OR body LIKE ?2 ESCAPE '\\') AND (?3 = 'all' OR status = ?3)
176
+ AND (?4 = '' OR project = ?4)
177
+ ORDER BY created_at DESC LIMIT 500`
178
+ )
179
+ .bind(userId, like, filter, project)
180
+ .all<DraftRow>();
181
+ return results ?? [];
182
+ }
183
+
184
+ export async function listShared(db: D1Database, githubId: number, q: string, filter: string, project: string): Promise<DraftRow[]> {
185
+ const like = likePattern(q);
186
+ const { results } = await db
187
+ .prepare(
188
+ `SELECT d.id, d.title, d.project, d.status, d.is_public, d.created_at, d.updated_at, u.login AS owner_login
189
+ FROM drafts d JOIN draft_access a ON a.draft_id = d.id JOIN users u ON u.id = d.owner_user_id
190
+ WHERE a.github_id = ?1 AND (?2 = '%%' OR d.title LIKE ?2 ESCAPE '\\' OR d.project LIKE ?2 ESCAPE '\\' OR d.body LIKE ?2 ESCAPE '\\') AND (?3 = 'all' OR d.status = ?3)
191
+ AND (?4 = '' OR d.project = ?4)
192
+ ORDER BY d.created_at DESC LIMIT 500`
193
+ )
194
+ .bind(githubId, like, filter, project)
195
+ .all<DraftRow>();
196
+ return results ?? [];
197
+ }
198
+
199
+ export async function listProjects(db: D1Database, userId: number, githubId: number): Promise<string[]> {
200
+ const { results } = await db
201
+ .prepare(
202
+ "SELECT project FROM drafts WHERE owner_user_id = ?1 " +
203
+ "UNION SELECT d.project FROM drafts d JOIN draft_access a ON a.draft_id = d.id WHERE a.github_id = ?2 " +
204
+ "ORDER BY project COLLATE NOCASE"
205
+ )
206
+ .bind(userId, githubId)
207
+ .all<{ project: string }>();
208
+ return (results ?? []).map((row) => row.project);
209
+ }