@whatcha/cli 0.1.0 → 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 (37) hide show
  1. package/README.md +185 -24
  2. package/dist/auth/session.js +50 -0
  3. package/dist/auth/session.js.map +1 -1
  4. package/dist/auth/token-store.js.map +1 -1
  5. package/dist/cli.js +36 -5
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/diaries.js +14 -3
  8. package/dist/commands/diaries.js.map +1 -1
  9. package/dist/commands/login.js +82 -7
  10. package/dist/commands/login.js.map +1 -1
  11. package/dist/commands/profiles.js +122 -11
  12. package/dist/commands/profiles.js.map +1 -1
  13. package/dist/commands/publish.js +81 -0
  14. package/dist/commands/publish.js.map +1 -0
  15. package/dist/commands/shared-diary.js +255 -0
  16. package/dist/commands/shared-diary.js.map +1 -0
  17. package/dist/commands/whoami.js +50 -0
  18. package/dist/commands/whoami.js.map +1 -0
  19. package/dist/commands/wiki.js +386 -0
  20. package/dist/commands/wiki.js.map +1 -0
  21. package/dist/commands/write.js +34 -3
  22. package/dist/commands/write.js.map +1 -1
  23. package/dist/http-client.js +16 -0
  24. package/dist/http-client.js.map +1 -1
  25. package/dist/lib/append-entry.js +60 -8
  26. package/dist/lib/append-entry.js.map +1 -1
  27. package/dist/lib/entry-date.js +22 -2
  28. package/dist/lib/entry-date.js.map +1 -1
  29. package/dist/lib/image-upload.js +126 -0
  30. package/dist/lib/image-upload.js.map +1 -0
  31. package/dist/lib/personal-access-token.js +46 -0
  32. package/dist/lib/personal-access-token.js.map +1 -0
  33. package/dist/lib/profile-family.js +29 -0
  34. package/dist/lib/profile-family.js.map +1 -0
  35. package/dist/lib/publication.js +55 -0
  36. package/dist/lib/publication.js.map +1 -0
  37. package/package.json +4 -4
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseDiaryNewArgs = parseDiaryNewArgs;
4
+ exports.runDiaryNew = runDiaryNew;
5
+ exports.parseInviteArgs = parseInviteArgs;
6
+ exports.runInvite = runInvite;
7
+ const node_util_1 = require("node:util");
8
+ const session_1 = require("../auth/session");
9
+ const config_1 = require("../config");
10
+ const errors_1 = require("../errors");
11
+ const diary_resolve_1 = require("../lib/diary-resolve");
12
+ const output_1 = require("../lib/output");
13
+ const profile_family_1 = require("../lib/profile-family");
14
+ /**
15
+ * `whatcha diary-new` and `whatcha invite` -- a diary written together
16
+ * (#1700), the way the app's "Write this diary with someone" does it
17
+ * (diary_share_with_someone.dart, #1686):
18
+ *
19
+ * 1. `POST /groups` -- a shared diary lives in a group; this one is named
20
+ * after the diary, and the caller owns it.
21
+ * 2. `POST /diaries` into that group -- readable by every member, the
22
+ * API's default for a shared group (#1527).
23
+ * 3. Members join through an invite: `POST /groups/:id/invites`, then
24
+ * `POST /invites/:token/accept` by whoever joins.
25
+ *
26
+ * The API has no "add this user" call; joining is always the joiner's own
27
+ * accept. For one of this login's sub-profiles (#1538) the CLI can do that
28
+ * accept itself, with a session for that profile used once and dropped
29
+ * (lib/profile-family.ts) -- that is what makes an exchange diary with an
30
+ * AI partner profile one command. Anybody else gets a one-use invite link
31
+ * to accept themselves, exactly what the app would hand out.
32
+ */
33
+ const MAX_NAME = 120;
34
+ /** The group's limit (`POST /groups`); the diary's own is 2000. */
35
+ const MAX_DESCRIPTION = 1000;
36
+ /**
37
+ * One handle into one group. A sub-profile of this login joins on the
38
+ * spot; the profile the CLI is signed in as already is a member; anyone
39
+ * else -- including the account itself, seen from a sub-profile, which the
40
+ * API will not issue a session for -- gets a link.
41
+ */
42
+ async function addToGroup(ctx, family, groupId, handle) {
43
+ const profile = (0, profile_family_1.findProfile)(family.profiles, handle);
44
+ const shown = profile?.username ? `@${profile.username}` : handle;
45
+ if (profile && profile.id === ctx.session.userId) {
46
+ return { handle: shown, profileId: profile.id, joined: true, alreadyMember: true, inviteUrl: null, expiresAt: null };
47
+ }
48
+ const joinsHere = profile !== undefined && profile.parentProfileId !== null;
49
+ const invite = await ctx.client.post(`/groups/${groupId}/invites`, {
50
+ maxUses: 1,
51
+ // Spent within this command when it joins here; a week to act on otherwise.
52
+ expiresInDays: joinsHere ? 1 : 7,
53
+ });
54
+ if (joinsHere) {
55
+ const asProfile = await (0, profile_family_1.clientAsProfile)(ctx.client, profile.id, ctx.forToken);
56
+ const accepted = await asProfile.post(`/invites/${encodeURIComponent(invite.token)}/accept`, {});
57
+ return { handle: shown, profileId: profile.id, joined: true, alreadyMember: accepted.alreadyMember, inviteUrl: null, expiresAt: null };
58
+ }
59
+ return {
60
+ handle: shown,
61
+ profileId: profile?.id ?? null,
62
+ joined: false,
63
+ alreadyMember: false,
64
+ inviteUrl: invite.inviteUrl,
65
+ expiresAt: invite.expires_at,
66
+ };
67
+ }
68
+ /** Every handle, each on its own: one refusal is reported with the rest still tried. */
69
+ async function addAll(ctx, groupId, handles) {
70
+ if (handles.length === 0)
71
+ return [];
72
+ const family = await ctx.client.get("/me/profiles");
73
+ const results = [];
74
+ for (const handle of handles) {
75
+ try {
76
+ results.push(await addToGroup(ctx, family, groupId, handle));
77
+ }
78
+ catch (err) {
79
+ if (!(err instanceof errors_1.ApiError))
80
+ throw err;
81
+ results.push({
82
+ handle,
83
+ profileId: (0, profile_family_1.findProfile)(family.profiles, handle)?.id ?? null,
84
+ joined: false,
85
+ alreadyMember: false,
86
+ inviteUrl: null,
87
+ expiresAt: null,
88
+ error: { code: err.code, message: err.message },
89
+ });
90
+ }
91
+ }
92
+ return results;
93
+ }
94
+ function memberLine(m) {
95
+ if (m.error)
96
+ return `${m.handle}: not added -- ${m.error.code}: ${m.error.message}`;
97
+ if (m.joined)
98
+ return m.alreadyMember ? `${m.handle}: already a member.` : `${m.handle}: joined.`;
99
+ return `${m.handle}: has to accept this invite (one use, until ${m.expiresAt}): ${m.inviteUrl}`;
100
+ }
101
+ async function context(deps) {
102
+ const resolved = deps.client ? null : await (0, session_1.authenticatedClient)();
103
+ const session = deps.session ?? resolved.session;
104
+ return {
105
+ client: deps.client ?? resolved.client,
106
+ session,
107
+ forToken: deps.clientForToken ?? (0, profile_family_1.bearerClients)(session.apiBaseUrl || (0, config_1.apiBaseUrl)()),
108
+ };
109
+ }
110
+ /** A @handle as typed, checked for being one; the `@` is optional. */
111
+ function handleArg(raw, flag) {
112
+ const handle = raw.trim();
113
+ if (!handle.replace(/^@/, ""))
114
+ throw new errors_1.CliUsageError(`${flag} needs a @handle.`);
115
+ return handle;
116
+ }
117
+ function validTimeZone(tz) {
118
+ try {
119
+ new Intl.DateTimeFormat("en-US", { timeZone: tz });
120
+ return true;
121
+ }
122
+ catch {
123
+ return false;
124
+ }
125
+ }
126
+ function parseDiaryNewArgs(argv) {
127
+ let values;
128
+ let positionals;
129
+ try {
130
+ ({ values, positionals } = (0, node_util_1.parseArgs)({
131
+ args: argv,
132
+ options: {
133
+ json: { type: "boolean", default: false },
134
+ with: { type: "string", multiple: true, default: [] },
135
+ timezone: { type: "string" },
136
+ description: { type: "string" },
137
+ },
138
+ allowPositionals: true,
139
+ }));
140
+ }
141
+ catch (err) {
142
+ throw new errors_1.CliUsageError(err.message);
143
+ }
144
+ if (!positionals[0])
145
+ throw new errors_1.CliUsageError("Name the diary: whatcha diary-new <name> [--with <@handle>]...");
146
+ if (positionals.length > 1) {
147
+ throw new errors_1.CliUsageError(`One diary per call; quote a name with spaces (got "${positionals.join(" ")}").`);
148
+ }
149
+ const name = positionals[0].trim();
150
+ if (!name)
151
+ throw new errors_1.CliUsageError("The diary's name is empty.");
152
+ if (name.length > MAX_NAME)
153
+ throw new errors_1.CliUsageError(`A diary's name is at most ${MAX_NAME} characters.`);
154
+ const timezone = values.timezone?.trim();
155
+ if (timezone !== undefined && !validTimeZone(timezone)) {
156
+ throw new errors_1.CliUsageError(`--timezone "${timezone}" is not an IANA time zone (e.g. Asia/Tokyo).`);
157
+ }
158
+ const description = values.description;
159
+ if (description !== undefined && description.length > MAX_DESCRIPTION) {
160
+ throw new errors_1.CliUsageError(`--description is at most ${MAX_DESCRIPTION} characters.`);
161
+ }
162
+ const handles = [];
163
+ for (const raw of values.with) {
164
+ const handle = handleArg(raw, "--with");
165
+ const key = handle.replace(/^@/, "").toLowerCase();
166
+ if (!handles.some((h) => h.replace(/^@/, "").toLowerCase() === key))
167
+ handles.push(handle);
168
+ }
169
+ return {
170
+ name,
171
+ with: handles,
172
+ ...(timezone !== undefined ? { timezone } : {}),
173
+ ...(description !== undefined ? { description } : {}),
174
+ json: values.json,
175
+ };
176
+ }
177
+ async function runDiaryNew(opts, deps = {}) {
178
+ const ctx = await context(deps);
179
+ const { client } = ctx;
180
+ const group = await client.post("/groups", {
181
+ name: opts.name,
182
+ ...(opts.description !== undefined ? { description: opts.description } : {}),
183
+ });
184
+ let diary;
185
+ try {
186
+ diary = await client.post("/diaries", {
187
+ name: opts.name,
188
+ groupId: group.id,
189
+ ...(opts.description !== undefined ? { description: opts.description } : {}),
190
+ ...(opts.timezone !== undefined ? { timezone: opts.timezone } : {}),
191
+ });
192
+ }
193
+ catch (err) {
194
+ // The group was made for this diary alone and is still empty: take it
195
+ // back rather than leave a stray group (on a free plan, the one group
196
+ // it may own). Best-effort -- the diary's own error is what to report.
197
+ await client.delete(`/groups/${group.id}?confirm=true`).catch(() => undefined);
198
+ throw err;
199
+ }
200
+ const members = await addAll(ctx, group.id, opts.with);
201
+ if (opts.json) {
202
+ (0, output_1.printJson)({ ok: true, diary, groupId: group.id, members });
203
+ }
204
+ else {
205
+ (0, output_1.printLine)(`Created the diary "${diary.name}" (tz=${diary.timezone}). diaryId=${diary.id}`);
206
+ for (const m of members)
207
+ (0, output_1.printLine)(` ${memberLine(m)}`);
208
+ }
209
+ if (members.some((m) => m.error)) {
210
+ (0, output_1.printErrorLine)("WARNING: the diary was created, but not everyone could be added. " +
211
+ `Retry each with: whatcha invite ${diary.id} <@handle>`);
212
+ return { exitCode: 2 };
213
+ }
214
+ return { exitCode: 0 };
215
+ }
216
+ function parseInviteArgs(argv) {
217
+ let values;
218
+ let positionals;
219
+ try {
220
+ ({ values, positionals } = (0, node_util_1.parseArgs)({
221
+ args: argv,
222
+ options: { json: { type: "boolean", default: false } },
223
+ allowPositionals: true,
224
+ }));
225
+ }
226
+ catch (err) {
227
+ throw new errors_1.CliUsageError(err.message);
228
+ }
229
+ if (positionals.length !== 2) {
230
+ throw new errors_1.CliUsageError("Run `whatcha invite <diary> <@handle>` -- one diary, one @handle (quote a name with spaces).");
231
+ }
232
+ return { diary: positionals[0], handle: handleArg(positionals[1], "invite"), json: values.json };
233
+ }
234
+ /**
235
+ * Add somebody to an existing diary's group. Membership is the group's: a
236
+ * member reads and writes every diary in it the group may (the API's ACL,
237
+ * not this file, decides which). Creating the invite is owner only -- the
238
+ * API's refusal is passed on as it came.
239
+ */
240
+ async function runInvite(opts, deps = {}) {
241
+ const ctx = await context(deps);
242
+ const diary = await (0, diary_resolve_1.resolveDiary)(ctx.client, opts.diary);
243
+ if (diary.groupType === "personal") {
244
+ throw new errors_1.CliUsageError(`"${diary.name}" is on your personal shelf, which nobody else can join. ` +
245
+ "Start a diary to share: whatcha diary-new <name> --with <@handle>");
246
+ }
247
+ const family = await ctx.client.get("/me/profiles");
248
+ const member = await addToGroup(ctx, family, diary.groupId, opts.handle);
249
+ if (opts.json)
250
+ (0, output_1.printJson)({ ok: true, diaryId: diary.id, groupId: diary.groupId, ...member });
251
+ else
252
+ (0, output_1.printLine)(memberLine(member));
253
+ return { exitCode: 0 };
254
+ }
255
+ //# sourceMappingURL=shared-diary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-diary.js","sourceRoot":"","sources":["../../src/commands/shared-diary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWhoamiArgs = parseWhoamiArgs;
4
+ exports.runWhoami = runWhoami;
5
+ const node_util_1 = require("node:util");
6
+ const session_1 = require("../auth/session");
7
+ const errors_1 = require("../errors");
8
+ const output_1 = require("../lib/output");
9
+ function parseWhoamiArgs(argv) {
10
+ let values;
11
+ try {
12
+ ({ values } = (0, node_util_1.parseArgs)({
13
+ args: argv,
14
+ options: { json: { type: "boolean", default: false } },
15
+ allowPositionals: false,
16
+ }));
17
+ }
18
+ catch (err) {
19
+ throw new errors_1.CliUsageError(err.message);
20
+ }
21
+ return { json: values.json };
22
+ }
23
+ async function runWhoami(opts, deps = {}) {
24
+ const resolved = deps.client ? null : await (0, session_1.authenticatedClient)();
25
+ const client = deps.client ?? resolved.client;
26
+ const session = deps.session ?? resolved.session;
27
+ const me = await client.get("/me");
28
+ const authKind = session.authKind ?? "session";
29
+ // Switched into a sub-profile when either credential was set aside.
30
+ const onSubProfile = Boolean(session.accountKey || session.accountRefreshToken);
31
+ if (opts.json) {
32
+ (0, output_1.printJson)({
33
+ ok: true,
34
+ id: me.id,
35
+ username: me.username,
36
+ displayName: me.displayName,
37
+ email: me.email,
38
+ authKind,
39
+ subProfile: onSubProfile,
40
+ apiBaseUrl: session.apiBaseUrl,
41
+ });
42
+ return { exitCode: 0 };
43
+ }
44
+ const name = me.displayName && me.displayName.length > 0 ? me.displayName : (me.username ?? me.id);
45
+ (0, output_1.printLine)(`@${me.username ?? "?"} ${name}${me.email ? ` <${me.email}>` : ""}`);
46
+ (0, output_1.printLine)(`Signed in with ${authKind === "key" ? "a personal access key" : "a session"}` +
47
+ `${onSubProfile ? ", switched into a sub-profile (whatcha switch --account to go back)" : ""}.`);
48
+ return { exitCode: 0 };
49
+ }
50
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":";;AAiBA,0CAYC;AASD,8BAkCC;AAxED,yCAAsC;AACtC,6CAAsD;AAEtD,sCAA0C;AAE1C,0CAAqD;AAYrD,SAAgB,eAAe,CAAC,IAAc;IAC5C,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,CAAC,EAAE,MAAM,EAAE,GAAG,IAAA,qBAAS,EAAC;YACtB,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACtD,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAC,CAAC;IACN,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,sBAAa,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAe,EAAE,CAAC;AAC1C,CAAC;AASM,KAAK,UAAU,SAAS,CAC7B,IAAmB,EACnB,OAA4D,EAAE;IAE9D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAA,6BAAmB,GAAE,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,QAAS,CAAC,MAAM,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,QAAS,CAAC,OAAO,CAAC;IAElD,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAK,KAAK,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC;IAC/C,oEAAoE;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEhF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAA,kBAAS,EAAC;YACR,EAAE,EAAE,IAAI;YACR,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,QAAQ,EAAE,EAAE,CAAC,QAAQ;YACrB,WAAW,EAAE,EAAE,CAAC,WAAW;YAC3B,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,QAAQ;YACR,UAAU,EAAE,YAAY;YACxB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACzB,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACnG,IAAA,kBAAS,EAAC,IAAI,EAAE,CAAC,QAAQ,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjF,IAAA,kBAAS,EACP,kBAAkB,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,WAAW,EAAE;QAC5E,GAAG,YAAY,CAAC,CAAC,CAAC,qEAAqE,CAAC,CAAC,CAAC,EAAE,GAAG,CAClG,CAAC;IACF,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;AACzB,CAAC"}