@andrestobelem/clone 0.1.3 → 0.2.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -23
  3. package/app.js +645 -0
  4. package/bin/clone.js +11 -230
  5. package/dist/actors.js +49 -0
  6. package/dist/actors.js.map +1 -0
  7. package/dist/automations.js +57 -0
  8. package/dist/automations.js.map +1 -0
  9. package/dist/cli.js +565 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/database.js +62 -0
  12. package/dist/database.js.map +1 -0
  13. package/dist/errors.js +46 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/issues.js +264 -0
  16. package/dist/issues.js.map +1 -0
  17. package/dist/paths.js +42 -0
  18. package/dist/paths.js.map +1 -0
  19. package/dist/projects.js +134 -0
  20. package/dist/projects.js.map +1 -0
  21. package/dist/recurring.js +45 -0
  22. package/dist/recurring.js.map +1 -0
  23. package/dist/schema.js +52 -0
  24. package/dist/schema.js.map +1 -0
  25. package/dist/seed.js +498 -0
  26. package/dist/seed.js.map +1 -0
  27. package/dist/server.js +232 -0
  28. package/dist/server.js.map +1 -0
  29. package/dist/sync.js +625 -0
  30. package/dist/sync.js.map +1 -0
  31. package/dist/teams.js +77 -0
  32. package/dist/teams.js.map +1 -0
  33. package/dist/time.js +4 -0
  34. package/dist/time.js.map +1 -0
  35. package/dist/types.js +2 -0
  36. package/dist/types.js.map +1 -0
  37. package/dist/validation.js +254 -0
  38. package/dist/validation.js.map +1 -0
  39. package/dist/workspace-helpers.js +75 -0
  40. package/dist/workspace-helpers.js.map +1 -0
  41. package/dist/workspace-mutations.js +160 -0
  42. package/dist/workspace-mutations.js.map +1 -0
  43. package/dist/workspace-reads.js +62 -0
  44. package/dist/workspace-reads.js.map +1 -0
  45. package/dist/workspace.js +8 -0
  46. package/dist/workspace.js.map +1 -0
  47. package/index.html +73 -0
  48. package/package.json +33 -4
  49. package/styles.css +108 -0
package/dist/server.js ADDED
@@ -0,0 +1,232 @@
1
+ import fs from "node:fs";
2
+ import http, {} from "node:http";
3
+ import path from "node:path";
4
+ import { URL } from "node:url";
5
+ import { openDatabase } from "./database.js";
6
+ import { CloneError, InvalidInputError } from "./errors.js";
7
+ import { rootDirectory } from "./paths.js";
8
+ import { initialize, mutate, prepare, withStorageLock } from "./sync.js";
9
+ import { actorRecord, actorRecords, bootstrap, dispatchMutation, issueRow, now, runDueRecurring, search, } from "./workspace.js";
10
+ const staticTypes = {
11
+ "index.html": "text/html; charset=utf-8",
12
+ "styles.css": "text/css; charset=utf-8",
13
+ "app.js": "application/javascript; charset=utf-8",
14
+ };
15
+ export async function startServer(paths, port, open) {
16
+ if (!fs.existsSync(paths.database)) {
17
+ if (fs.existsSync(paths.snapshotDirectory))
18
+ throw new InvalidInputError("Snapshot found. Run clone sync import first.");
19
+ await withStorageLock(paths, () => initialize(paths, false));
20
+ }
21
+ else {
22
+ await withStorageLock(paths, () => prepare(paths));
23
+ }
24
+ const host = process.env.CLONE_HOST ?? "127.0.0.1";
25
+ const server = http.createServer((request, response) => void handle(paths, request, response));
26
+ await new Promise((resolve, reject) => {
27
+ server.once("error", reject);
28
+ server.listen(port, host, resolve);
29
+ });
30
+ const url = `http://${host}:${port}`;
31
+ console.log(`Clone running at ${url} (SQLite: ${paths.database})`);
32
+ if (open)
33
+ openBrowser(url);
34
+ const timer = setInterval(() => {
35
+ void withStorageLock(paths, () => mutate(paths, (database) => runDueRecurring(database, paths))).catch((error) => {
36
+ console.error(`Recurring issue scheduler error: ${error instanceof Error ? error.message : String(error)}`);
37
+ });
38
+ }, 30_000);
39
+ timer.unref();
40
+ await new Promise((resolve) => {
41
+ const stop = () => {
42
+ server.close(() => {
43
+ clearInterval(timer);
44
+ resolve();
45
+ });
46
+ };
47
+ process.once("SIGINT", stop);
48
+ process.once("SIGTERM", stop);
49
+ });
50
+ }
51
+ async function handle(paths, request, response) {
52
+ if (process.env.CLONE_ACCESS_LOG === "1")
53
+ console.log(`${request.method} ${request.url}`);
54
+ try {
55
+ const url = new URL(request.url ?? "/", "http://127.0.0.1");
56
+ const route = decodeURIComponent(url.pathname);
57
+ if (!route.startsWith("/api/")) {
58
+ serveStatic(route, response);
59
+ return;
60
+ }
61
+ if (request.method === "GET") {
62
+ const result = await withStorageLock(paths, () => apiRead(paths, route, url.searchParams));
63
+ if (result instanceof AttachmentResponse) {
64
+ sendAttachment(response, result);
65
+ return;
66
+ }
67
+ sendJson(response, result.body, result.status);
68
+ return;
69
+ }
70
+ if (!["POST", "PUT", "PATCH", "DELETE"].includes(request.method ?? "")) {
71
+ sendJson(response, { error: "Not found" }, 404);
72
+ return;
73
+ }
74
+ const body = await readBody(request);
75
+ const result = await withStorageLock(paths, () => mutate(paths, (database) => dispatchMutation(database, request.method, route, body, paths)));
76
+ const status = Number(result._status ?? 200);
77
+ delete result._status;
78
+ sendJson(response, result, status);
79
+ }
80
+ catch (error) {
81
+ const status = error instanceof CloneError
82
+ ? error.code === "sync_conflict"
83
+ ? 409
84
+ : error.code === "pending_export"
85
+ ? 503
86
+ : 400
87
+ : 500;
88
+ const body = {
89
+ error: error instanceof Error ? error.message : String(error),
90
+ };
91
+ if (error instanceof CloneError)
92
+ Object.assign(body, error.details);
93
+ else
94
+ ((body.error = "Internal error"),
95
+ (body.detail = error instanceof Error ? error.message : String(error)));
96
+ sendJson(response, body, status);
97
+ }
98
+ }
99
+ function apiRead(paths, route, query) {
100
+ const database = openDatabase(paths);
101
+ try {
102
+ if (route === "/api/bootstrap")
103
+ return json(bootstrap(database));
104
+ if (route === "/api/health")
105
+ return json({ ok: true, database: "sqlite", mode: "local-single-user" });
106
+ if (route === "/api/export")
107
+ return json({ ...bootstrap(database), exportedAt: now() });
108
+ if (route === "/api/search")
109
+ return json(search(database, query.get("q") ?? "", query.get("scope") ?? "All"));
110
+ const actor = route.match(/^\/api\/(actors|agents)(?:\/(\d+))?$/);
111
+ if (actor) {
112
+ const kind = actor[1] === "agents" ? "agent" : null;
113
+ if (actor[2]) {
114
+ const record = actorRecord(database, Number(actor[2]));
115
+ return !record || (kind && record.kind !== kind)
116
+ ? json({ error: "Actor not found" }, 404)
117
+ : json(record);
118
+ }
119
+ return json(actorRecords(database, kind, query.get("all") === "true"));
120
+ }
121
+ const attachment = route.match(/^\/api\/attachments\/(\d+)$/);
122
+ if (attachment) {
123
+ const row = database
124
+ .prepare("SELECT * FROM issue_attachments WHERE id=?")
125
+ .get(Number(attachment[1]));
126
+ if (!row)
127
+ return json({ error: "Attachment not found" }, 404);
128
+ const content = fs.readFileSync(path.join(paths.attachmentsDirectory, String(row.storage_name)));
129
+ return new AttachmentResponse(content, String(row.name), String(row.content_type));
130
+ }
131
+ const issue = route.match(/^\/api\/issues\/([^/]+)$/);
132
+ if (issue) {
133
+ const row = database
134
+ .prepare("SELECT id FROM issues WHERE identifier=?")
135
+ .get(issue[1]);
136
+ return row
137
+ ? json(issueRow(database, row.id))
138
+ : json({ error: "Issue not found" }, 404);
139
+ }
140
+ const project = route.match(/^\/api\/projects\/(\d+)$/);
141
+ if (project) {
142
+ const record = bootstrap(database).projects.find((item) => Number(item.id) === Number(project[1]));
143
+ return record ? json(record) : json({ error: "Project not found" }, 404);
144
+ }
145
+ return json({ error: "Not found" }, 404);
146
+ }
147
+ finally {
148
+ database.close();
149
+ }
150
+ }
151
+ function serveStatic(route, response) {
152
+ const name = route === "/" ? "index.html" : route.slice(1);
153
+ if (!staticTypes[name]) {
154
+ response.writeHead(404);
155
+ response.end();
156
+ return;
157
+ }
158
+ const target = path.join(rootDirectory, name);
159
+ const content = fs.readFileSync(target);
160
+ response.writeHead(200, {
161
+ "Content-Type": staticTypes[name],
162
+ "Content-Length": content.length,
163
+ });
164
+ response.end(content);
165
+ }
166
+ async function readBody(request) {
167
+ const declared = Number(request.headers["content-length"] ?? 0);
168
+ if (!Number.isFinite(declared) || declared < 0)
169
+ throw new InvalidInputError("Content-Length must not be negative");
170
+ if (declared > 5_000_000)
171
+ throw new InvalidInputError("Request body too large");
172
+ const chunks = [];
173
+ let size = 0;
174
+ for await (const chunk of request) {
175
+ const buffer = Buffer.from(chunk);
176
+ size += buffer.length;
177
+ if (size > 5_000_000)
178
+ throw new InvalidInputError("Request body too large");
179
+ chunks.push(buffer);
180
+ }
181
+ if (!size)
182
+ return {};
183
+ const value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
184
+ if (!value || typeof value !== "object" || Array.isArray(value))
185
+ throw new InvalidInputError("Request body must be an object");
186
+ return value;
187
+ }
188
+ function sendJson(response, body, status = 200) {
189
+ const content = Buffer.from(JSON.stringify(body), "utf8");
190
+ response.writeHead(status, {
191
+ "Content-Type": "application/json; charset=utf-8",
192
+ "Content-Length": content.length,
193
+ "Cache-Control": "no-store",
194
+ });
195
+ response.end(content);
196
+ }
197
+ function sendAttachment(response, result) {
198
+ const fallback = result.name.replace(/[^A-Za-z0-9._-]/g, "_") || "attachment";
199
+ response.writeHead(200, {
200
+ "Content-Type": result.type,
201
+ "Content-Length": result.content.length,
202
+ "Content-Disposition": `attachment; filename="${fallback}"; filename*=UTF-8''${encodeURIComponent(result.name)}`,
203
+ "X-Content-Type-Options": "nosniff",
204
+ "Cache-Control": "no-store",
205
+ });
206
+ response.end(result.content);
207
+ }
208
+ function openBrowser(url) {
209
+ const command = process.platform === "darwin"
210
+ ? ["open", url]
211
+ : process.platform === "win32"
212
+ ? ["cmd", "/d", "/s", "/c", "start", "", url]
213
+ : ["xdg-open", url];
214
+ import("node:child_process").then(({ spawn }) => spawn(command[0], command.slice(1), {
215
+ detached: true,
216
+ stdio: "ignore",
217
+ }).unref());
218
+ }
219
+ class AttachmentResponse {
220
+ content;
221
+ name;
222
+ type;
223
+ constructor(content, name, type) {
224
+ this.content = content;
225
+ this.name = name;
226
+ this.type = type;
227
+ }
228
+ }
229
+ function json(body, status = 200) {
230
+ return { body, status };
231
+ }
232
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}