@whatcha/cli 0.0.0-stage → 0.3.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.
Files changed (59) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +345 -2
  3. package/dist/auth/gotrue-client.js +64 -0
  4. package/dist/auth/gotrue-client.js.map +1 -0
  5. package/dist/auth/session.js +147 -0
  6. package/dist/auth/session.js.map +1 -0
  7. package/dist/auth/token-store.js +165 -0
  8. package/dist/auth/token-store.js.map +1 -0
  9. package/dist/cli.js +134 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/diaries.js +52 -0
  12. package/dist/commands/diaries.js.map +1 -0
  13. package/dist/commands/login.js +292 -0
  14. package/dist/commands/login.js.map +1 -0
  15. package/dist/commands/profiles.js +287 -0
  16. package/dist/commands/profiles.js.map +1 -0
  17. package/dist/commands/publish.js +81 -0
  18. package/dist/commands/publish.js.map +1 -0
  19. package/dist/commands/read.js +77 -0
  20. package/dist/commands/read.js.map +1 -0
  21. package/dist/commands/shared-diary.js +255 -0
  22. package/dist/commands/shared-diary.js.map +1 -0
  23. package/dist/commands/whoami.js +50 -0
  24. package/dist/commands/whoami.js.map +1 -0
  25. package/dist/commands/wiki.js +386 -0
  26. package/dist/commands/wiki.js.map +1 -0
  27. package/dist/commands/write.js +106 -0
  28. package/dist/commands/write.js.map +1 -0
  29. package/dist/config.js +47 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/errors.js +46 -0
  32. package/dist/errors.js.map +1 -0
  33. package/dist/http-client.js +102 -0
  34. package/dist/http-client.js.map +1 -0
  35. package/dist/index.js +16 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/lib/append-entry.js +193 -0
  38. package/dist/lib/append-entry.js.map +1 -0
  39. package/dist/lib/diary-resolve.js +50 -0
  40. package/dist/lib/diary-resolve.js.map +1 -0
  41. package/dist/lib/entry-date.js +96 -0
  42. package/dist/lib/entry-date.js.map +1 -0
  43. package/dist/lib/entry-find.js +39 -0
  44. package/dist/lib/entry-find.js.map +1 -0
  45. package/dist/lib/image-upload.js +126 -0
  46. package/dist/lib/image-upload.js.map +1 -0
  47. package/dist/lib/jwt.js +25 -0
  48. package/dist/lib/jwt.js.map +1 -0
  49. package/dist/lib/output.js +29 -0
  50. package/dist/lib/output.js.map +1 -0
  51. package/dist/lib/personal-access-token.js +46 -0
  52. package/dist/lib/personal-access-token.js.map +1 -0
  53. package/dist/lib/profile-family.js +29 -0
  54. package/dist/lib/profile-family.js.map +1 -0
  55. package/dist/lib/publication.js +55 -0
  56. package/dist/lib/publication.js.map +1 -0
  57. package/dist/types.js +6 -0
  58. package/dist/types.js.map +1 -0
  59. package/package.json +46 -4
@@ -0,0 +1,386 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWikiArgs = parseWikiArgs;
4
+ exports.appendedWikiBody = appendedWikiBody;
5
+ exports.runWiki = runWiki;
6
+ const node_util_1 = require("node:util");
7
+ const session_1 = require("../auth/session");
8
+ const errors_1 = require("../errors");
9
+ const image_upload_1 = require("../lib/image-upload");
10
+ const output_1 = require("../lib/output");
11
+ /**
12
+ * `whatcha wiki list | read | write | cover` -- the Experience Wiki from a
13
+ * terminal (#1664), against the same routes the app uses:
14
+ *
15
+ * Public Square GET /experience-pages[?q] GET|PUT /experience-pages/:tag
16
+ * a group (#1348) GET /groups/:groupId/experience-pages GET|PUT /groups/:groupId/experience-pages/:tag
17
+ * the cover PUT|DELETE <page>/cover (#1667)
18
+ *
19
+ * Who may read or write which page -- a group's members, a page's Owner and
20
+ * edit policy (#1344), a lock -- is the API's call, not this file's: every
21
+ * refusal is the API's own error, printed as it came.
22
+ *
23
+ * Writing keeps the CLI's one promise: nothing somebody else wrote is
24
+ * removed. `wiki write` appends below the page's current text by default;
25
+ * `--replace` saves the given text as the page's new version, and the
26
+ * previous versions stay in the page's history either way (a wiki edit is a
27
+ * new revision, never an overwrite of one).
28
+ *
29
+ * Images (#1667): `--image <file>` uploads a local image into the page's
30
+ * group and appends `![<file name>](media:<id>)` for it below the text;
31
+ * `--cover <file>` uploads one and makes it the page's cover in the same
32
+ * save. See lib/image-upload.ts for the upload and its limits.
33
+ */
34
+ const MAX_BODY = 20_000;
35
+ const MAX_TAG = 64;
36
+ const MAX_MESSAGE = 200;
37
+ /** A page shows at most 50 images (the API's MAX_PAGE_IMAGES); one write adds at most this many. */
38
+ const MAX_IMAGES_PER_WRITE = 20;
39
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
40
+ /** A stand-in media id, the length of a real one, for sizing a body before uploading. */
41
+ const PLACEHOLDER_ID = "00000000-0000-0000-0000-000000000000";
42
+ const USAGE = "Usage:\n" +
43
+ " whatcha wiki list [--search <text>] [--group <group-id>] [--limit N] [--cursor <c>] [--json]\n" +
44
+ " whatcha wiki read <page> [--group <group-id>] [--json]\n" +
45
+ ' whatcha wiki write <page> --text "..." [--image <file>]... [--cover <file>] [--replace] [--message "..."] [--group <group-id>] [--json]\n' +
46
+ " whatcha wiki cover <page> <file> | --clear [--group <group-id>] [--json]";
47
+ const FLAGS = ["search", "limit", "cursor", "text", "replace", "message", "image", "cover", "clear"];
48
+ function parseWikiArgs(argv) {
49
+ const [action, ...rest] = argv;
50
+ let values, positionals;
51
+ try {
52
+ ({ values, positionals } = (0, node_util_1.parseArgs)({
53
+ args: rest,
54
+ options: {
55
+ json: { type: "boolean", default: false },
56
+ group: { type: "string" },
57
+ search: { type: "string" },
58
+ limit: { type: "string" },
59
+ cursor: { type: "string" },
60
+ text: { type: "string" },
61
+ replace: { type: "boolean", default: false },
62
+ message: { type: "string" },
63
+ image: { type: "string", multiple: true },
64
+ cover: { type: "string" },
65
+ clear: { type: "boolean", default: false },
66
+ },
67
+ allowPositionals: true,
68
+ }));
69
+ }
70
+ catch (err) {
71
+ throw new errors_1.CliUsageError(err.message);
72
+ }
73
+ const json = values.json;
74
+ const group = values.group;
75
+ if (group !== undefined && !UUID.test(group)) {
76
+ throw new errors_1.CliUsageError(`--group takes a group id (a UUID; \`whatcha diaries --json\` shows each diary's groupId), got "${group}".`);
77
+ }
78
+ const only = (allowed) => {
79
+ for (const name of FLAGS) {
80
+ const v = values[name];
81
+ if (!allowed.includes(name) && v !== undefined && v !== false) {
82
+ throw new errors_1.CliUsageError(`--${name} does not apply to \`whatcha wiki ${action}\`.\n${USAGE}`);
83
+ }
84
+ }
85
+ };
86
+ switch (action) {
87
+ case "list": {
88
+ only(["search", "limit", "cursor"]);
89
+ if (positionals.length > 0)
90
+ throw new errors_1.CliUsageError(`Unexpected argument: "${positionals[0]}"\n${USAGE}`);
91
+ let limit;
92
+ if (values.limit !== undefined) {
93
+ limit = Number(values.limit);
94
+ if (!Number.isInteger(limit) || limit < 1 || limit > 100)
95
+ throw new errors_1.CliUsageError("--limit must be a whole number from 1 to 100.");
96
+ }
97
+ const search = values.search?.trim();
98
+ if (search !== undefined && search.length > MAX_TAG)
99
+ throw new errors_1.CliUsageError(`--search is at most ${MAX_TAG} characters.`);
100
+ return { action, json, group, search: search || undefined, limit, cursor: values.cursor };
101
+ }
102
+ case "read": {
103
+ only([]);
104
+ return { action, json, group, page: pageArg(positionals) };
105
+ }
106
+ case "write": {
107
+ only(["text", "replace", "message", "image", "cover"]);
108
+ const page = pageArg(positionals);
109
+ const images = values.image ?? [];
110
+ if (images.length > MAX_IMAGES_PER_WRITE)
111
+ throw new errors_1.CliUsageError(`At most ${MAX_IMAGES_PER_WRITE} --image files per write.`);
112
+ if (images.some((f) => !f.trim()))
113
+ throw new errors_1.CliUsageError("--image takes a file path.");
114
+ const cover = values.cover;
115
+ if (cover !== undefined && !cover.trim())
116
+ throw new errors_1.CliUsageError("--cover takes a file path.");
117
+ const text = values.text ?? "";
118
+ // Images alone are something to write; nothing at all is not.
119
+ if (text.trim().length === 0 && images.length === 0) {
120
+ throw new errors_1.CliUsageError("--text is required and must not be empty (or give at least one --image).");
121
+ }
122
+ if (text.length > MAX_BODY)
123
+ throw new errors_1.CliUsageError(`--text is at most ${MAX_BODY} characters.`);
124
+ const message = values.message?.trim();
125
+ if (message !== undefined && message.length > MAX_MESSAGE)
126
+ throw new errors_1.CliUsageError(`--message is at most ${MAX_MESSAGE} characters.`);
127
+ return {
128
+ action,
129
+ json,
130
+ group,
131
+ page,
132
+ text,
133
+ replace: values.replace,
134
+ message: message || undefined,
135
+ images,
136
+ cover,
137
+ };
138
+ }
139
+ case "cover": {
140
+ only(["clear"]);
141
+ const clear = values.clear;
142
+ const [pageRaw, image, extra] = positionals;
143
+ if (extra !== undefined)
144
+ throw new errors_1.CliUsageError(`Unexpected extra argument: "${extra}" (quote a page name that has spaces).`);
145
+ const page = pageArg(pageRaw === undefined ? [] : [pageRaw]);
146
+ if (clear && image !== undefined)
147
+ throw new errors_1.CliUsageError("Give an image file or --clear, not both.");
148
+ if (!clear && (image === undefined || !image.trim())) {
149
+ throw new errors_1.CliUsageError(`Which image? Give a file, or --clear to remove the cover.\n${USAGE}`);
150
+ }
151
+ return { action, json, group, page, image: clear ? undefined : image, clear };
152
+ }
153
+ default:
154
+ throw new errors_1.CliUsageError(action ? `Unknown wiki action "${action}".\n${USAGE}` : USAGE);
155
+ }
156
+ }
157
+ function pageArg(positionals) {
158
+ if (positionals.length === 0)
159
+ throw new errors_1.CliUsageError(`Which page? Give its tag, e.g. "Kyoto Tower".\n${USAGE}`);
160
+ if (positionals.length > 1)
161
+ throw new errors_1.CliUsageError(`Unexpected extra argument: "${positionals[1]}" (quote a page name that has spaces).`);
162
+ // A leading "#" is how a tag is written in an entry; the page is the tag itself.
163
+ const page = positionals[0].trim().replace(/^#/, "").trim();
164
+ if (!page)
165
+ throw new errors_1.CliUsageError("The page name must not be empty.");
166
+ if (page.length > MAX_TAG)
167
+ throw new errors_1.CliUsageError(`A page name is at most ${MAX_TAG} characters.`);
168
+ return page;
169
+ }
170
+ function pagesPath(group) {
171
+ return group ? `/groups/${group}/experience-pages` : "/experience-pages";
172
+ }
173
+ function pagePath(page, group) {
174
+ return `${pagesPath(group)}/${encodeURIComponent(page)}`;
175
+ }
176
+ /** The page, or null when it does not exist (yet) -- or this account cannot see it, which the API answers the same way. */
177
+ async function findPage(client, page, group) {
178
+ try {
179
+ return await client.get(pagePath(page, group));
180
+ }
181
+ catch (err) {
182
+ if (err instanceof errors_1.ApiError && err.status === 404)
183
+ return null;
184
+ throw err;
185
+ }
186
+ }
187
+ /** Mirrors `whatcha write`'s own append: existing text, trimmed, a blank line, then the new text. */
188
+ function appendedWikiBody(existing, text) {
189
+ const trimmed = existing.trimEnd();
190
+ return trimmed ? `${trimmed}\n\n${text}` : text;
191
+ }
192
+ /** The group a page's images are uploaded into: the page's own (Public Square's for the public wiki). */
193
+ function uploadGroupOf(page, group) {
194
+ return page?.groupId ?? group ?? image_upload_1.PUBLIC_SQUARE_GROUP_ID;
195
+ }
196
+ async function runWiki(opts, deps = {}) {
197
+ const client = deps.client ?? (await (0, session_1.authenticatedClient)()).client;
198
+ switch (opts.action) {
199
+ case "list":
200
+ return listPages(client, opts);
201
+ case "read":
202
+ return readPage(client, opts);
203
+ case "write":
204
+ return writePage(client, opts);
205
+ case "cover":
206
+ return setCover(client, opts);
207
+ }
208
+ }
209
+ async function listPages(client, opts) {
210
+ const page = await client.getPage(pagesPath(opts.group), {
211
+ q: opts.search,
212
+ limit: opts.limit !== undefined ? String(opts.limit) : undefined,
213
+ cursor: opts.cursor,
214
+ });
215
+ if (opts.json) {
216
+ (0, output_1.printJson)({
217
+ ok: true,
218
+ groupId: opts.group ?? null,
219
+ pages: page.items.map((p) => ({ id: p.id, tag: p.tagLabel, slug: p.tagSlug, preview: p.preview, updatedAt: p.updatedAt })),
220
+ nextCursor: page.nextCursor,
221
+ hasNext: page.hasNext,
222
+ });
223
+ return { exitCode: 0 };
224
+ }
225
+ if (page.items.length === 0) {
226
+ (0, output_1.printLine)(opts.search ? `No wiki pages match "${opts.search}".` : "No wiki pages yet.");
227
+ return { exitCode: 0 };
228
+ }
229
+ for (const p of page.items) {
230
+ (0, output_1.printLine)(`${p.tagLabel}${p.preview ? ` -- ${p.preview.replace(/\s+/g, " ").slice(0, 80)}` : ""}`);
231
+ }
232
+ if (page.hasNext && page.nextCursor)
233
+ (0, output_1.printLine)(`(more: --cursor ${page.nextCursor})`);
234
+ return { exitCode: 0 };
235
+ }
236
+ async function readPage(client, opts) {
237
+ const page = await findPage(client, opts.page, opts.group);
238
+ if (!page) {
239
+ if (opts.json)
240
+ (0, output_1.printJson)({ ok: true, found: false, page: opts.page, groupId: opts.group ?? null });
241
+ else
242
+ (0, output_1.printLine)(`No wiki page "${opts.page}"${opts.group ? " in that group" : ""} (or this account cannot see it).`);
243
+ return { exitCode: 0 };
244
+ }
245
+ const media = page.media ?? [];
246
+ if (opts.json) {
247
+ (0, output_1.printJson)({
248
+ ok: true,
249
+ found: true,
250
+ id: page.id,
251
+ tag: page.tagLabel,
252
+ slug: page.tagSlug,
253
+ groupId: page.groupId,
254
+ revisionId: page.revisionId,
255
+ revisionCount: page.revisionCount,
256
+ isLocked: page.isLocked,
257
+ lastEditedAt: page.lastEditedAt,
258
+ lastEditedBy: page.lastEditedBy?.username ?? null,
259
+ body: page.body,
260
+ media: media.map((m) => ({ id: m.id, url: m.url, mimeType: m.mimeType ?? null, altText: m.altText ?? null })),
261
+ coverMediaAssetId: page.coverMediaAssetId ?? null,
262
+ coverUrl: page.coverUrl ?? null,
263
+ });
264
+ return { exitCode: 0 };
265
+ }
266
+ const by = page.lastEditedBy?.username ? ` by @${page.lastEditedBy.username}` : "";
267
+ (0, output_1.printLine)(`${page.tagLabel} (${page.revisionCount} version${page.revisionCount === 1 ? "" : "s"}; last edited ${page.lastEditedAt ?? "?"}${by})`);
268
+ if (page.isLocked)
269
+ (0, output_1.printLine)("locked: only moderators can edit this page.");
270
+ if (page.coverUrl)
271
+ (0, output_1.printLine)(`cover: ${page.coverUrl}`);
272
+ (0, output_1.printLine)("");
273
+ (0, output_1.printLine)(page.body);
274
+ if (media.length > 0) {
275
+ // The body says `media:<id>`; this is where each one can be opened.
276
+ // Signed URLs, so they stop working after about an hour.
277
+ (0, output_1.printLine)("");
278
+ (0, output_1.printLine)("Images (links valid for about an hour):");
279
+ for (const m of media)
280
+ (0, output_1.printLine)(` media:${m.id} ${m.url}`);
281
+ }
282
+ return { exitCode: 0 };
283
+ }
284
+ /** Each --image file and the --cover file, read and checked before anything goes over the network. */
285
+ async function readImages(opts) {
286
+ const inline = [];
287
+ for (const path of opts.images)
288
+ inline.push(await (0, image_upload_1.readImageFile)(path));
289
+ const cover = opts.cover !== undefined ? await (0, image_upload_1.readImageFile)(opts.cover) : undefined;
290
+ return { inline, cover };
291
+ }
292
+ async function writePage(client, opts) {
293
+ const files = await readImages(opts);
294
+ const before = await findPage(client, opts.page, opts.group);
295
+ const compose = (ids) => {
296
+ const added = [opts.text.trim() ? opts.text : "", ...files.inline.map((f, i) => (0, image_upload_1.wikiImageRef)(f.fileName, ids[i]))]
297
+ .filter((part) => part !== "")
298
+ .join("\n\n");
299
+ return opts.replace || !before ? added : appendedWikiBody(before.body, added);
300
+ };
301
+ // Checked before uploading, so a page that would be too long costs no
302
+ // orphaned uploads. Every reference is the same length whatever its id.
303
+ const sized = compose(files.inline.map(() => PLACEHOLDER_ID));
304
+ if (sized.length > MAX_BODY) {
305
+ throw new errors_1.CliUsageError(`The page would be ${sized.length} characters with this text; the limit is ${MAX_BODY}. Nothing was written.`);
306
+ }
307
+ const group = uploadGroupOf(before, opts.group);
308
+ const ids = [];
309
+ for (const file of files.inline)
310
+ ids.push(await (0, image_upload_1.uploadImage)(client, group, file));
311
+ const coverId = files.cover ? await (0, image_upload_1.uploadImage)(client, group, files.cover) : undefined;
312
+ const saved = await client.put(pagePath(opts.page, opts.group), {
313
+ body: compose(ids),
314
+ ...(opts.message ? { message: opts.message } : {}),
315
+ ...(coverId ? { coverMediaAssetId: coverId } : {}),
316
+ });
317
+ const mode = !before ? "created" : opts.replace ? "replaced" : "appended";
318
+ // The PUT carries no "expected revision", so an edit that landed between
319
+ // the read and the write would be left out of the new current text. It is
320
+ // not lost -- it is a revision in the page's history -- but say so loudly,
321
+ // the way `whatcha write` reports an append it could not confirm.
322
+ const raced = before !== null && saved.revisionCount !== before.revisionCount + 1;
323
+ if (opts.json) {
324
+ (0, output_1.printJson)({
325
+ ok: true,
326
+ mode,
327
+ id: saved.id,
328
+ tag: saved.tagLabel,
329
+ groupId: saved.groupId,
330
+ revisionId: saved.revisionId,
331
+ revisionCount: saved.revisionCount,
332
+ concurrentEdit: raced,
333
+ images: files.inline.map((f, i) => ({ file: f.path, mediaAssetId: ids[i] })),
334
+ coverMediaAssetId: coverId ?? null,
335
+ });
336
+ }
337
+ else {
338
+ const verb = mode === "created" ? "Created" : mode === "replaced" ? "Saved a new version of" : "Appended to";
339
+ const extras = [
340
+ ids.length > 0 ? `${ids.length} image${ids.length === 1 ? "" : "s"}` : "",
341
+ coverId ? "a new cover" : "",
342
+ ].filter(Boolean);
343
+ (0, output_1.printLine)(`${verb} the wiki page "${saved.tagLabel}" (version ${saved.revisionCount}${extras.length ? `; ${extras.join(", ")}` : ""}).`);
344
+ }
345
+ if (raced) {
346
+ (0, output_1.printErrorLine)(`WARNING: somebody else edited "${saved.tagLabel}" while whatcha was writing to it. Their version is in the ` +
347
+ "page's history; check the page and merge it back by hand if it is missing from the current text.");
348
+ return { exitCode: 2 };
349
+ }
350
+ return { exitCode: 0 };
351
+ }
352
+ async function setCover(client, opts) {
353
+ const file = opts.image !== undefined ? await (0, image_upload_1.readImageFile)(opts.image) : undefined;
354
+ const page = await findPage(client, opts.page, opts.group);
355
+ if (!page) {
356
+ throw new errors_1.CliUsageError(`No wiki page "${opts.page}"${opts.group ? " in that group" : ""} (or this account cannot see it). ` +
357
+ "Create it first: whatcha wiki write <page> --text \"...\" --cover <file>");
358
+ }
359
+ const path = `${pagePath(opts.page, opts.group)}/cover`;
360
+ let saved;
361
+ if (file) {
362
+ const mediaAssetId = await (0, image_upload_1.uploadImage)(client, uploadGroupOf(page, opts.group), file);
363
+ saved = await client.put(path, { mediaAssetId });
364
+ }
365
+ else {
366
+ saved = await client.delete(path);
367
+ }
368
+ if (opts.json) {
369
+ (0, output_1.printJson)({
370
+ ok: true,
371
+ id: saved.id,
372
+ tag: saved.tagLabel,
373
+ groupId: saved.groupId,
374
+ coverMediaAssetId: saved.coverMediaAssetId ?? null,
375
+ coverUrl: saved.coverUrl ?? null,
376
+ });
377
+ }
378
+ else if (file) {
379
+ (0, output_1.printLine)(`Set the cover of the wiki page "${saved.tagLabel}".${saved.coverUrl ? `\ncover: ${saved.coverUrl}` : ""}`);
380
+ }
381
+ else {
382
+ (0, output_1.printLine)(`Removed the cover of the wiki page "${saved.tagLabel}".`);
383
+ }
384
+ return { exitCode: 0 };
385
+ }
386
+ //# sourceMappingURL=wiki.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki.js","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWriteArgs = parseWriteArgs;
4
+ exports.runWrite = runWrite;
5
+ const node_util_1 = require("node:util");
6
+ const session_1 = require("../auth/session");
7
+ const errors_1 = require("../errors");
8
+ const diary_resolve_1 = require("../lib/diary-resolve");
9
+ const entry_date_1 = require("../lib/entry-date");
10
+ const append_entry_1 = require("../lib/append-entry");
11
+ const output_1 = require("../lib/output");
12
+ function parseWriteArgs(argv) {
13
+ let values, positionals;
14
+ try {
15
+ ({ values, positionals } = (0, node_util_1.parseArgs)({
16
+ args: argv,
17
+ options: {
18
+ json: { type: "boolean", default: false },
19
+ text: { type: "string" },
20
+ date: { type: "string" },
21
+ time: { type: "string" },
22
+ title: { type: "string" },
23
+ tag: { type: "string", multiple: true },
24
+ },
25
+ allowPositionals: true,
26
+ }));
27
+ }
28
+ catch (err) {
29
+ throw new errors_1.CliUsageError(err.message);
30
+ }
31
+ if (positionals.length === 0) {
32
+ throw new errors_1.CliUsageError('Usage: whatcha write <diary> --text "..." [--title "..."] [--tag <tag>]... [--date YYYY-MM-DD] [--time HH:MM]');
33
+ }
34
+ if (positionals.length > 1)
35
+ throw new errors_1.CliUsageError(`Unexpected extra argument: "${positionals[1]}"`);
36
+ if (!values.text)
37
+ throw new errors_1.CliUsageError("--text is required.");
38
+ if (values.text.trim().length === 0)
39
+ throw new errors_1.CliUsageError("--text must not be empty.");
40
+ const title = values.title;
41
+ if (title !== undefined) {
42
+ if (title.trim().length === 0)
43
+ throw new errors_1.CliUsageError("--title must not be empty.");
44
+ if (title.trim().length > append_entry_1.MAX_TITLE_LENGTH)
45
+ throw new errors_1.CliUsageError(`--title is at most ${append_entry_1.MAX_TITLE_LENGTH} characters.`);
46
+ }
47
+ const rawTags = values.tag ?? [];
48
+ for (const t of rawTags) {
49
+ if (t.trim().length === 0)
50
+ throw new errors_1.CliUsageError("--tag must not be empty.");
51
+ if (t.trim().length > append_entry_1.MAX_TAG_LENGTH)
52
+ throw new errors_1.CliUsageError(`A --tag is at most ${append_entry_1.MAX_TAG_LENGTH} characters: "${t}".`);
53
+ }
54
+ const tags = (0, append_entry_1.normalizeTags)(rawTags);
55
+ if (tags.length > append_entry_1.MAX_TAGS)
56
+ throw new errors_1.CliUsageError(`At most ${append_entry_1.MAX_TAGS} tags per entry.`);
57
+ return {
58
+ json: values.json,
59
+ diary: positionals[0],
60
+ text: values.text,
61
+ date: values.date,
62
+ time: values.time,
63
+ title: title?.trim(),
64
+ tags,
65
+ };
66
+ }
67
+ async function runWrite(opts, deps = {}) {
68
+ const client = deps.client ?? (await (0, session_1.authenticatedClient)()).client;
69
+ const diary = await (0, diary_resolve_1.resolveDiary)(client, opts.diary);
70
+ const occurredAt = (0, entry_date_1.resolveOccurredAt)({ date: opts.date, time: opts.time }, diary.timezone);
71
+ const result = await (0, append_entry_1.writeEntry)(client, diary.id, occurredAt, opts.text, { title: opts.title, tags: opts.tags });
72
+ if (opts.json) {
73
+ (0, output_1.printJson)({
74
+ ok: true,
75
+ diaryId: diary.id,
76
+ entryId: result.entryId,
77
+ mode: result.mode,
78
+ verified: result.verified,
79
+ occurredAt: occurredAt.toISOString(),
80
+ title: result.title,
81
+ tags: result.tags,
82
+ titleKept: result.titleKept,
83
+ });
84
+ }
85
+ else {
86
+ const verb = result.mode === "created" ? "Created" : "Appended to";
87
+ (0, output_1.printLine)(`${verb} the entry for ${diary.name} (${occurredAt.toISOString()}). entryId=${result.entryId}`);
88
+ }
89
+ if (result.titleKept) {
90
+ // Not an error -- the text and tags landed -- but the person asked for
91
+ // a title and did not get it, so say why (on stderr, like the warning
92
+ // below, so --json stdout stays one object).
93
+ (0, output_1.printErrorLine)(`Note: this entry already has a title ("${result.title}"), which was kept; --title was not applied.`);
94
+ }
95
+ if (result.verified === false) {
96
+ // Loud on purpose, on stderr even in --json mode -- see
97
+ // append-entry.ts's verifyAppend comment. stdout still carries only
98
+ // the one JSON object the --json contract promises; the exit code is
99
+ // what a script should actually branch on.
100
+ (0, output_1.printErrorLine)("WARNING: could not confirm the previous text survived the append. Check this entry by hand " +
101
+ `(whatcha read ${JSON.stringify(opts.diary)}${opts.date ? ` --date ${opts.date}` : ""}) before writing to it again.`);
102
+ return { exitCode: 2 };
103
+ }
104
+ return { exitCode: 0 };
105
+ }
106
+ //# sourceMappingURL=write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_API_URL = void 0;
7
+ exports.apiBaseUrl = apiBaseUrl;
8
+ exports.supabaseCredentials = supabaseCredentials;
9
+ exports.configDir = configDir;
10
+ exports.credentialsFilePath = credentialsFilePath;
11
+ const node_os_1 = __importDefault(require("node:os"));
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ /** Same two servers openapi.yaml declares. Anything else needs --api-url. */
14
+ exports.DEFAULT_API_URL = "https://whatareyoudo.ing/api/v1";
15
+ function apiBaseUrl() {
16
+ return process.env.WHATCHA_API_URL?.trim() || exports.DEFAULT_API_URL;
17
+ }
18
+ /**
19
+ * Opt-in direct-GoTrue login (auth/gotrue-client.ts) -- both or neither.
20
+ * See that file's header comment for why this is not a default: this repo
21
+ * has no Supabase URL/anon key a headless checkout can read.
22
+ */
23
+ function supabaseCredentials() {
24
+ const url = process.env.WHATCHA_SUPABASE_URL?.trim();
25
+ const anonKey = process.env.WHATCHA_SUPABASE_ANON_KEY?.trim();
26
+ return url && anonKey ? { url, anonKey } : undefined;
27
+ }
28
+ /**
29
+ * Where the file-store fallback (and, on Linux/macOS, nothing else) keeps
30
+ * its one file. `WHATCHA_CONFIG_DIR` is how the tests point this at a
31
+ * throwaway directory instead of the developer's real one -- see
32
+ * tests/token-store.test.ts.
33
+ */
34
+ function configDir() {
35
+ const override = process.env.WHATCHA_CONFIG_DIR;
36
+ if (override)
37
+ return override;
38
+ if (process.platform === "win32") {
39
+ return node_path_1.default.join(process.env.APPDATA || node_os_1.default.homedir(), "whatcha");
40
+ }
41
+ const xdg = process.env.XDG_CONFIG_HOME;
42
+ return node_path_1.default.join(xdg || node_path_1.default.join(node_os_1.default.homedir(), ".config"), "whatcha");
43
+ }
44
+ function credentialsFilePath() {
45
+ return node_path_1.default.join(configDir(), "credentials.json");
46
+ }
47
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAMA,gCAEC;AAOD,kDAIC;AAQD,8BAQC;AAED,kDAEC;AAvCD,sDAAyB;AACzB,0DAA6B;AAE7B,6EAA6E;AAChE,QAAA,eAAe,GAAG,iCAAiC,CAAC;AAEjE,SAAgB,UAAU;IACxB,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,uBAAe,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,SAAgB,mBAAmB;IACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,IAAI,EAAE,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAC;IAC9D,OAAO,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS;IACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAChD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,mBAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,iBAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,OAAO,mBAAI,CAAC,IAAI,CAAC,GAAG,IAAI,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;AACzE,CAAC;AAED,SAAgB,mBAAmB;IACjC,OAAO,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACpD,CAAC"}
package/dist/errors.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CliUsageError = exports.ApiError = void 0;
4
+ /**
5
+ * Mirrors the API's error envelope (apps/api/src/core/request/errors.ts):
6
+ * `{ error: { code, message, details } }`. Thrown by WhatchaClient for any
7
+ * non-2xx response so commands can branch on `code` instead of parsing
8
+ * `message` (the API's own comment on ApiErrorCode says the same: message is
9
+ * for humans, code is for control flow).
10
+ */
11
+ class ApiError extends Error {
12
+ status;
13
+ code;
14
+ details;
15
+ constructor(status, code, message, details) {
16
+ super(message);
17
+ this.status = status;
18
+ this.code = code;
19
+ this.details = details;
20
+ this.name = "ApiError";
21
+ }
22
+ /**
23
+ * True when this looks like a server that does not know the `appendBody`
24
+ * field yet -- pre-#1422-fix, or STRICT_REQUEST_BODIES turned on for a
25
+ * schema that has not added it. `parseBody` on the API side reports a
26
+ * dropped key as `{ field: "appendBody", reason: "unrecognized_key" }`
27
+ * inside a VALIDATION_ERROR. See lib/append-entry.ts for why this matters:
28
+ * it is the only case where `whatcha write` falls back to reading the
29
+ * entry and merging the body itself instead of trusting the flag.
30
+ */
31
+ isUnrecognizedAppendBodyFlag() {
32
+ if (this.code !== "VALIDATION_ERROR" || !Array.isArray(this.details))
33
+ return false;
34
+ return this.details.some((d) => d.field === "appendBody" && d.reason === "unrecognized_key");
35
+ }
36
+ }
37
+ exports.ApiError = ApiError;
38
+ /** A bad command line -- unknown flag, missing required argument, malformed --date. Never a network or API problem. */
39
+ class CliUsageError extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "CliUsageError";
43
+ }
44
+ }
45
+ exports.CliUsageError = CliUsageError;
46
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAOA;;;;;;GAMG;AACH,MAAa,QAAS,SAAQ,KAAK;IAEtB;IACA;IAEA;IAJX,YACW,MAAc,EACd,IAAY,EACrB,OAAe,EACN,OAAoD;QAE7D,KAAK,CAAC,OAAO,CAAC,CAAC;QALN,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QAEZ,YAAO,GAAP,OAAO,CAA6C;QAG7D,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;;;OAQG;IACH,4BAA4B;QAC1B,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACnF,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,YAAY,IAAI,CAAC,CAAC,MAAM,KAAK,kBAAkB,CAAC,CAAC;IAC/F,CAAC;CACF;AAxBD,4BAwBC;AAED,uHAAuH;AACvH,MAAa,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AALD,sCAKC"}