@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
@@ -1,7 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_TAGS = exports.MAX_TAG_LENGTH = exports.MAX_TITLE_LENGTH = void 0;
4
+ exports.normalizeTags = normalizeTags;
5
+ exports.mergeHeader = mergeHeader;
3
6
  exports.writeEntry = writeEntry;
4
7
  const errors_1 = require("../errors");
8
+ /** The API's own limits (entries-content.ts `contentSchema`). */
9
+ exports.MAX_TITLE_LENGTH = 200;
10
+ exports.MAX_TAG_LENGTH = 64;
11
+ exports.MAX_TAGS = 32;
5
12
  function existingEntryIdFrom(err) {
6
13
  if (err.status !== 409 || err.code !== "VERSION_CONFLICT")
7
14
  return null;
@@ -13,10 +20,44 @@ function headerOf(entry) {
13
20
  title: entry.title,
14
21
  mood: entry.mood,
15
22
  location: entry.location,
23
+ // Only sent back when the API sent them: an older server that does not
24
+ // know the fields must not be handed keys it would drop or refuse.
25
+ ...(entry.locationLat !== undefined ? { locationLat: entry.locationLat } : {}),
26
+ ...(entry.locationLng !== undefined ? { locationLng: entry.locationLng } : {}),
16
27
  tags: entry.tags,
17
28
  coverMediaAssetId: entry.coverMediaAssetId,
18
29
  };
19
30
  }
31
+ /** Tags trimmed, empties dropped, exact duplicates removed -- the app's own rule (entry editor's _addTag). */
32
+ function normalizeTags(tags) {
33
+ const out = [];
34
+ for (const raw of tags) {
35
+ const tag = raw.trim();
36
+ if (tag && !out.includes(tag))
37
+ out.push(tag);
38
+ }
39
+ return out;
40
+ }
41
+ /**
42
+ * The header an append saves: the entry's own, with `meta` merged in under
43
+ * the append rule. Exported for the tests.
44
+ */
45
+ function mergeHeader(header, meta) {
46
+ const wanted = meta.title?.trim();
47
+ const hasTitle = Boolean(header.title && header.title.trim());
48
+ const title = hasTitle ? header.title : wanted ? wanted : header.title;
49
+ const tags = normalizeTags([...(header.tags ?? []), ...(meta.tags ?? [])]);
50
+ // Kept as the entry had them when nothing new was asked for -- a merge
51
+ // that only re-normalised somebody else's tags would still be a change.
52
+ const finalTags = meta.tags && meta.tags.length > 0 ? tags : header.tags;
53
+ if (finalTags.length > exports.MAX_TAGS) {
54
+ throw new errors_1.CliUsageError(`This entry would end up with ${finalTags.length} tags; the limit is ${exports.MAX_TAGS}. Nothing was written.`);
55
+ }
56
+ return {
57
+ header: { ...header, title, tags: finalTags },
58
+ titleKept: Boolean(wanted && hasTitle && header.title.trim() !== wanted),
59
+ };
60
+ }
20
61
  /**
21
62
  * What the stored body should read as after appending `text`, mirroring the
22
63
  * API's own `appendedBody` (apps/api/src/modules/diaries/entries/
@@ -60,14 +101,24 @@ function expectedAppendedBody(existingBody, text) {
60
101
  * Either way, nothing is ever PATCHed as a plain replacement of a body this
61
102
  * function did not just read.
62
103
  */
63
- async function writeEntry(client, diaryId, occurredAt, text) {
104
+ async function writeEntry(client, diaryId, occurredAt, text, meta = {}) {
105
+ const title = meta.title?.trim() || undefined;
106
+ const tags = normalizeTags(meta.tags ?? []);
64
107
  try {
65
108
  const created = await client.post("/entries", {
66
109
  diaryId,
67
110
  occurredAt: occurredAt.toISOString(),
68
- content: { body: text },
111
+ content: { body: text, ...(title ? { title } : {}), ...(tags.length > 0 ? { tags } : {}) },
69
112
  });
70
- return { entryId: created.id, headCommitId: created.headCommitId, mode: "created", verified: null };
113
+ return {
114
+ entryId: created.id,
115
+ headCommitId: created.headCommitId,
116
+ mode: "created",
117
+ verified: null,
118
+ title: title ?? null,
119
+ tags,
120
+ titleKept: false,
121
+ };
71
122
  }
72
123
  catch (err) {
73
124
  if (!(err instanceof errors_1.ApiError))
@@ -75,12 +126,13 @@ async function writeEntry(client, diaryId, occurredAt, text) {
75
126
  const existingEntryId = existingEntryIdFrom(err);
76
127
  if (!existingEntryId)
77
128
  throw err;
78
- return appendToExisting(client, existingEntryId, text);
129
+ return appendToExisting(client, existingEntryId, text, { title, tags });
79
130
  }
80
131
  }
81
- async function appendToExisting(client, entryId, text) {
132
+ async function appendToExisting(client, entryId, text, meta) {
82
133
  const existing = await client.get(`/entries/${entryId}`);
83
- const header = headerOf(existing);
134
+ const { header, titleKept } = mergeHeader(headerOf(existing), meta);
135
+ const after = { title: header.title, tags: header.tags, titleKept };
84
136
  try {
85
137
  const saved = await client.patch(`/entries/${entryId}`, {
86
138
  content: { body: text, ...header },
@@ -88,7 +140,7 @@ async function appendToExisting(client, entryId, text) {
88
140
  expectedHeadCommitId: existing.headCommitId,
89
141
  });
90
142
  const verified = await verifyAppend(client, entryId, existing.body, text);
91
- return { entryId, headCommitId: saved.headCommitId, mode: "appended", verified };
143
+ return { entryId, headCommitId: saved.headCommitId, mode: "appended", verified, ...after };
92
144
  }
93
145
  catch (err) {
94
146
  if (!(err instanceof errors_1.ApiError))
@@ -113,7 +165,7 @@ async function appendToExisting(client, entryId, text) {
113
165
  throw fallbackErr;
114
166
  });
115
167
  const verified = await verifyAppend(client, entryId, existing.body, text);
116
- return { entryId, headCommitId: saved.headCommitId, mode: "appended-fallback", verified };
168
+ return { entryId, headCommitId: saved.headCommitId, mode: "appended-fallback", verified, ...after };
117
169
  }
118
170
  }
119
171
  function concurrentWriteError(err) {
@@ -1 +1 @@
1
- {"version":3,"file":"append-entry.js","sourceRoot":"","sources":["../../src/lib/append-entry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"append-entry.js","sourceRoot":"","sources":["../../src/lib/append-entry.ts"],"names":[],"mappings":"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"}
@@ -53,10 +53,30 @@ function timeKeyInTimeZone(date, timeZone) {
53
53
  */
54
54
  function zonedTimeToUtc(dateStr, timeStr, timeZone) {
55
55
  const asIfUtc = new Date(`${dateStr}T${timeStr}:00.000Z`);
56
- const readInZone = new Date(asIfUtc.toLocaleString("en-US", { timeZone }));
57
- const diff = asIfUtc.getTime() - readInZone.getTime();
56
+ const diff = asIfUtc.getTime() - wallClockAsUtcMs(asIfUtc, timeZone);
58
57
  return new Date(asIfUtc.getTime() + diff);
59
58
  }
59
+ /**
60
+ * The wall-clock reading of `instant` in `timeZone`, re-read as if it were
61
+ * UTC. Assembled from formatToParts and Date.UTC rather than by parsing a
62
+ * toLocaleString() back through `new Date()` -- that parse happens in the
63
+ * MACHINE's timezone, which shifted every --date/--time by the machine's
64
+ * own UTC offset on anything not set to UTC.
65
+ */
66
+ function wallClockAsUtcMs(instant, timeZone) {
67
+ const parts = new Intl.DateTimeFormat("en-US", {
68
+ timeZone,
69
+ year: "numeric",
70
+ month: "2-digit",
71
+ day: "2-digit",
72
+ hour: "2-digit",
73
+ minute: "2-digit",
74
+ second: "2-digit",
75
+ hourCycle: "h23",
76
+ }).formatToParts(instant);
77
+ const get = (type) => Number(parts.find((p) => p.type === type)?.value);
78
+ return Date.UTC(get("year"), get("month") - 1, get("day"), get("hour"), get("minute"), get("second"));
79
+ }
60
80
  /**
61
81
  * Resolves `--date`/`--time` into the `occurredAt` instant to send the API,
62
82
  * defaulting both to "now" in the diary's own timezone -- not the machine's,
@@ -1 +1 @@
1
- {"version":3,"file":"entry-date.js","sourceRoot":"","sources":["../../src/lib/entry-date.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entry-date.js","sourceRoot":"","sources":["../../src/lib/entry-date.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PUBLIC_SQUARE_GROUP_ID = exports.MAX_UPLOAD_BYTES = void 0;
4
+ exports.sniffImageType = sniffImageType;
5
+ exports.readImageFile = readImageFile;
6
+ exports.uploadImage = uploadImage;
7
+ exports.wikiImageRef = wikiImageRef;
8
+ const promises_1 = require("node:fs/promises");
9
+ const node_path_1 = require("node:path");
10
+ const errors_1 = require("../errors");
11
+ /**
12
+ * Local image files to media assets, for `whatcha wiki write --image/--cover`
13
+ * and `whatcha wiki cover` (#1667). `readImageFile` also checks the file
14
+ * `whatcha profile-add --avatar` sends (#1699).
15
+ *
16
+ * The upload is the app's own three steps -- `POST /uploads` (into the
17
+ * page's group), PUT the bytes to the signed URL, `POST /uploads/:id/complete`
18
+ * -- so the server applies the same limits it applies to an entry's photos.
19
+ * The checks here are those same limits, made before anything is sent, so a
20
+ * wrong file is a clear message instead of a half-done upload:
21
+ *
22
+ * - at most 40 MB (the API's UPLOAD_LIMITS.maxFileBytes);
23
+ * - a JPEG, PNG, WebP, GIF or AVIF image -- the image types the API accepts,
24
+ * and a wiki page shows nothing else. The type is read from the file's
25
+ * first bytes, the way the server resolves it; the extension only fills in
26
+ * for an AVIF variant the magic-number check does not recognise.
27
+ */
28
+ exports.MAX_UPLOAD_BYTES = 40 * 1024 * 1024;
29
+ /** Public Square's group: where the public wiki's images are uploaded. */
30
+ exports.PUBLIC_SQUARE_GROUP_ID = "00000000-0000-0000-0000-0000000000aa";
31
+ const BY_EXTENSION = {
32
+ ".jpg": "image/jpeg",
33
+ ".jpeg": "image/jpeg",
34
+ ".png": "image/png",
35
+ ".webp": "image/webp",
36
+ ".gif": "image/gif",
37
+ ".avif": "image/avif",
38
+ };
39
+ function ascii(bytes, start, end) {
40
+ return String.fromCharCode(...bytes.subarray(start, end));
41
+ }
42
+ /** The image type the bytes are, or null. Mirrors the API's core/media/image-type.ts. */
43
+ function sniffImageType(bytes) {
44
+ if (bytes.length >= 3 && bytes[0] === 0xff && bytes[1] === 0xd8 && bytes[2] === 0xff)
45
+ return "image/jpeg";
46
+ if (bytes.length >= 8 && bytes[0] === 0x89 && ascii(bytes, 1, 4) === "PNG" && bytes[4] === 0x0d && bytes[5] === 0x0a) {
47
+ return "image/png";
48
+ }
49
+ if (bytes.length >= 6 && (ascii(bytes, 0, 6) === "GIF87a" || ascii(bytes, 0, 6) === "GIF89a"))
50
+ return "image/gif";
51
+ if (bytes.length >= 12 && ascii(bytes, 0, 4) === "RIFF" && ascii(bytes, 8, 12) === "WEBP")
52
+ return "image/webp";
53
+ if (bytes.length >= 16 && ascii(bytes, 4, 8) === "ftyp") {
54
+ const box = Math.min(((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0, bytes.length, 64);
55
+ const brands = [ascii(bytes, 8, 12)];
56
+ for (let i = 16; i + 4 <= box; i += 4)
57
+ brands.push(ascii(bytes, i, i + 4));
58
+ if (brands.includes("avif") || brands.includes("avis"))
59
+ return "image/avif";
60
+ }
61
+ return null;
62
+ }
63
+ function megabytes(n) {
64
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
65
+ }
66
+ /** Reads and checks one image file. Throws CliUsageError with the reason when it cannot be uploaded. */
67
+ async function readImageFile(path) {
68
+ let size;
69
+ try {
70
+ const info = await (0, promises_1.stat)(path);
71
+ if (!info.isFile())
72
+ throw new errors_1.CliUsageError(`${path} is not a file.`);
73
+ size = info.size;
74
+ }
75
+ catch (err) {
76
+ if (err instanceof errors_1.CliUsageError)
77
+ throw err;
78
+ throw new errors_1.CliUsageError(`Cannot read ${path}: ${err.code ?? err.message}`);
79
+ }
80
+ // Before reading it: a 2 GB video passed by mistake should not be loaded to find out.
81
+ if (size > exports.MAX_UPLOAD_BYTES) {
82
+ throw new errors_1.CliUsageError(`${path} is ${megabytes(size)}; an upload is at most ${exports.MAX_UPLOAD_BYTES / (1024 * 1024)} MB.`);
83
+ }
84
+ if (size === 0)
85
+ throw new errors_1.CliUsageError(`${path} is empty.`);
86
+ const handle = await (0, promises_1.open)(path, "r");
87
+ let bytes;
88
+ try {
89
+ bytes = new Uint8Array(await handle.readFile());
90
+ }
91
+ finally {
92
+ await handle.close();
93
+ }
94
+ if (bytes.length > exports.MAX_UPLOAD_BYTES) {
95
+ throw new errors_1.CliUsageError(`${path} is ${megabytes(bytes.length)}; an upload is at most ${exports.MAX_UPLOAD_BYTES / (1024 * 1024)} MB.`);
96
+ }
97
+ const byExtension = BY_EXTENSION[(0, node_path_1.extname)(path).toLowerCase()];
98
+ const sniffed = sniffImageType(bytes);
99
+ // An ISO-BMFF file (ftyp box) named .avif whose brands this check does not list.
100
+ const contentType = sniffed ?? (byExtension === "image/avif" && ascii(bytes, 4, 8) === "ftyp" ? byExtension : null);
101
+ if (!contentType) {
102
+ throw new errors_1.CliUsageError(`${path} is not a JPEG, PNG, WebP, GIF or AVIF image; nothing else can be shown.`);
103
+ }
104
+ return { path, fileName: (0, node_path_1.basename)(path), contentType, bytes };
105
+ }
106
+ /** `POST /uploads` -> PUT to the signed URL -> `POST /uploads/:id/complete`. The new media asset's id. */
107
+ async function uploadImage(client, groupId, image) {
108
+ const ticket = await client.post("/uploads", {
109
+ fileName: image.fileName,
110
+ contentType: image.contentType,
111
+ size: image.bytes.length,
112
+ groupId,
113
+ });
114
+ await client.putBytes(ticket.uploadUrl, ticket.headers ?? { "Content-Type": image.contentType }, image.bytes);
115
+ await client.post(`/uploads/${ticket.mediaAssetId}/complete`);
116
+ return ticket.mediaAssetId;
117
+ }
118
+ /**
119
+ * `![alt](media:<id>)`, the wiki's image reference. The alt text is the file
120
+ * name; a `]` or line break in it would end the reference early.
121
+ */
122
+ function wikiImageRef(alt, mediaAssetId) {
123
+ const clean = alt.replace(/[[\]\r\n]+/g, " ").replace(/\s+/g, " ").trim();
124
+ return `![${clean}](media:${mediaAssetId})`;
125
+ }
126
+ //# sourceMappingURL=image-upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-upload.js","sourceRoot":"","sources":["../../src/lib/image-upload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WHERE_KEYS_ARE_ISSUED = exports.PERSONAL_ACCESS_TOKEN_PREFIX = void 0;
4
+ exports.looksLikePersonalAccessToken = looksLikePersonalAccessToken;
5
+ exports.isWellFormedPersonalAccessToken = isWellFormedPersonalAccessToken;
6
+ exports.translateKeyError = translateKeyError;
7
+ const errors_1 = require("../errors");
8
+ /**
9
+ * Personal access keys (#1469, server side in PR #1550; CLI side #1663).
10
+ *
11
+ * The server tells a key from a Supabase session JWT by this literal prefix
12
+ * alone (apps/api/src/modules/account/auth/access-tokens.ts,
13
+ * `looksLikeAccessToken`), and so does the CLI: a key is sent as-is as the
14
+ * Bearer credential, never refreshed, and never exchanged for anything.
15
+ */
16
+ exports.PERSONAL_ACCESS_TOKEN_PREFIX = "whatcha_pat_";
17
+ /** `whatcha_pat_<24 hex>_<64 hex>` -- the server's own WIRE_FORM. */
18
+ const WIRE_FORM = /^whatcha_pat_[0-9a-f]{24}_[0-9a-f]{64}$/;
19
+ function looksLikePersonalAccessToken(raw) {
20
+ return raw.trim().startsWith(exports.PERSONAL_ACCESS_TOKEN_PREFIX);
21
+ }
22
+ function isWellFormedPersonalAccessToken(raw) {
23
+ return WIRE_FORM.test(raw.trim());
24
+ }
25
+ exports.WHERE_KEYS_ARE_ISSUED = "Profile → Connected apps and keys";
26
+ /**
27
+ * A key's refusals, said in terms of the key.
28
+ *
29
+ * The API answers a revoked key exactly like one that never existed -- 401
30
+ * UNAUTHENTICATED, "Invalid access token." -- on purpose (revocation deletes
31
+ * the row; acceptAccessToken). For a session that means "sign in again"; for
32
+ * a key the only fix is a new key, so a script gets a code it can branch on
33
+ * instead of the generic one. Expiry (TOKEN_EXPIRED) likewise.
34
+ */
35
+ function translateKeyError(err) {
36
+ if (!(err instanceof errors_1.ApiError))
37
+ return err;
38
+ if (err.status === 401 && err.code === "TOKEN_EXPIRED") {
39
+ return new errors_1.ApiError(401, "KEY_EXPIRED", `This personal access key has expired. Issue a new one in ${exports.WHERE_KEYS_ARE_ISSUED}, then run \`whatcha login --key <key>\`.`);
40
+ }
41
+ if (err.status === 401) {
42
+ return new errors_1.ApiError(401, "KEY_REVOKED", `This personal access key was revoked or is not valid. Issue a new one in ${exports.WHERE_KEYS_ARE_ISSUED}, then run \`whatcha login --key <key>\`.`);
43
+ }
44
+ return err;
45
+ }
46
+ //# sourceMappingURL=personal-access-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"personal-access-token.js","sourceRoot":"","sources":["../../src/lib/personal-access-token.ts"],"names":[],"mappings":";;;AAeA,oEAEC;AAED,0EAEC;AAaD,8CAiBC;AAnDD,sCAAqC;AAErC;;;;;;;GAOG;AACU,QAAA,4BAA4B,GAAG,cAAc,CAAC;AAE3D,qEAAqE;AACrE,MAAM,SAAS,GAAG,yCAAyC,CAAC;AAE5D,SAAgB,4BAA4B,CAAC,GAAW;IACtD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,oCAA4B,CAAC,CAAC;AAC7D,CAAC;AAED,SAAgB,+BAA+B,CAAC,GAAW;IACzD,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAEY,QAAA,qBAAqB,GAAG,mCAAmC,CAAC;AAEzE;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAAC,GAAY;IAC5C,IAAI,CAAC,CAAC,GAAG,YAAY,iBAAQ,CAAC;QAAE,OAAO,GAAG,CAAC;IAC3C,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACvD,OAAO,IAAI,iBAAQ,CACjB,GAAG,EACH,aAAa,EACb,4DAA4D,6BAAqB,2CAA2C,CAC7H,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,IAAI,iBAAQ,CACjB,GAAG,EACH,aAAa,EACb,4EAA4E,6BAAqB,2CAA2C,CAC7I,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findProfile = findProfile;
4
+ exports.bearerClients = bearerClients;
5
+ exports.clientAsProfile = clientAsProfile;
6
+ const http_client_1 = require("../http-client");
7
+ /** A profile of this login by @handle (the `@` optional, case-insensitive) or id. */
8
+ function findProfile(profiles, target) {
9
+ const wanted = target.replace(/^@/, "").toLowerCase();
10
+ return profiles.find((p) => p.id === target || (p.username ?? "").toLowerCase() === wanted);
11
+ }
12
+ function bearerClients(baseUrl) {
13
+ return (accessToken) => new http_client_1.FetchWhatchaClient(baseUrl, async () => `Bearer ${accessToken}`);
14
+ }
15
+ /**
16
+ * A client that IS one of this login's sub-profiles, for the rest of one
17
+ * command -- the session `whatcha switch` would save, used and dropped
18
+ * instead. Some things only a profile can do for itself (set its own
19
+ * avatar, accept an invite into a group), and the saved session must not
20
+ * change under a command that was not asked to switch.
21
+ *
22
+ * The API reaches only sub-profiles of the caller's own family, never the
23
+ * account itself; its refusal is passed on as it came.
24
+ */
25
+ async function clientAsProfile(client, profileId, forToken) {
26
+ const issued = await client.post(`/me/profiles/${profileId}/session`, {});
27
+ return forToken(issued.accessToken);
28
+ }
29
+ //# sourceMappingURL=profile-family.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-family.js","sourceRoot":"","sources":["../../src/lib/profile-family.ts"],"names":[],"mappings":";;AA+BA,kCAGC;AAKD,sCAEC;AAYD,0CAOC;AA5DD,gDAAwE;AA8BxE,qFAAqF;AACrF,SAAgB,WAAW,CAAC,QAA6B,EAAE,MAAc;IACvE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;AAC9F,CAAC;AAKD,SAAgB,aAAa,CAAC,OAAe;IAC3C,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,gCAAkB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,eAAe,CACnC,MAAqB,EACrB,SAAiB,EACjB,QAAwB;IAExB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAiB,gBAAgB,SAAS,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publicDiaryUrl = publicDiaryUrl;
4
+ exports.publicDiaryIds = publicDiaryIds;
5
+ /**
6
+ * Whether anybody, signed in or not, can read a diary -- and where (#1701).
7
+ *
8
+ * Publishing belongs to the group, not the diary: `PUT /groups/:id/publication`
9
+ * (owner only; the app's "Publish" card on a group's page) makes a shared
10
+ * group public, and with it every diary in it that the group's members can
11
+ * read. A diary kept to its creator (`visibility: "private"`) stays private
12
+ * inside a published group. That is the API's own test (PUBLIC_SCOPE in
13
+ * public-square-repository.ts), read here from what the app reads: the
14
+ * group's `isPublic` from `GET /groups`, the diary's `visibility` from
15
+ * `GET /diaries/:id`.
16
+ */
17
+ /** The web page a published diary is read at: the site's origin, which is the API's (`/api/v1` hangs off it). */
18
+ function publicDiaryUrl(apiBaseUrl, diaryId) {
19
+ return `${new URL(apiBaseUrl).origin}/diaries/${diaryId}`;
20
+ }
21
+ async function publishedGroupIds(client) {
22
+ const ids = new Set();
23
+ let cursor;
24
+ for (;;) {
25
+ const page = await client.getPage("/groups", { limit: "50", cursor });
26
+ for (const g of page.items)
27
+ if (g.isPublic)
28
+ ids.add(g.id);
29
+ if (!page.hasNext || !page.nextCursor)
30
+ break;
31
+ cursor = page.nextCursor;
32
+ }
33
+ return ids;
34
+ }
35
+ /**
36
+ * The ids of the diaries among `diaries` that are public. One `GET /groups`
37
+ * walk, plus one `GET /diaries/:id` per diary in a published group only --
38
+ * a shelf with nothing published costs a single extra call.
39
+ */
40
+ async function publicDiaryIds(client, diaries) {
41
+ const published = new Set();
42
+ const shared = diaries.filter((d) => d.groupType !== "personal");
43
+ if (shared.length === 0)
44
+ return published;
45
+ const groups = await publishedGroupIds(client);
46
+ for (const d of shared) {
47
+ if (!groups.has(d.groupId))
48
+ continue;
49
+ const detail = await client.get(`/diaries/${d.id}`);
50
+ if (detail.visibility === "group")
51
+ published.add(d.id);
52
+ }
53
+ return published;
54
+ }
55
+ //# sourceMappingURL=publication.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publication.js","sourceRoot":"","sources":["../../src/lib/publication.ts"],"names":[],"mappings":";;AAiBA,wCAEC;AAwBD,wCAWC;AAnDD;;;;;;;;;;;GAWG;AAEH,iHAAiH;AACjH,SAAgB,cAAc,CAAC,UAAkB,EAAE,OAAe;IAChE,OAAO,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC;AAC5D,CAAC;AAOD,KAAK,UAAU,iBAAiB,CAAC,MAAqB;IACpD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,IAAI,MAA0B,CAAC;IAC/B,SAAS,CAAC;QACR,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAgB,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,CAAC,QAAQ;gBAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,MAAM;QAC7C,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,cAAc,CAAC,MAAqB,EAAE,OAAgB;IAC1E,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,SAAS;QACrC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAsC,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzF,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@whatcha/cli",
3
- "version": "0.1.0",
4
- "description": "Official command-line client for what-are-you-do-ing (whatareyoudo.ing) -- login, list diaries, write and read entries.",
3
+ "version": "0.3.0",
4
+ "description": "Official command-line client for what-are-you-do-ing (whatareyoudo.ing) -- login (password or personal access key), list diaries, write and read entries, switch profiles, read and write the Experience Wiki, with images.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://whatareyoudo.ing/cli",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://gitea.lovekapibarasan.org/LoveKapibarasan/what-are-you-do-ing.git",
9
+ "url": "git+https://github.com/what-are-you-do-ing/whatcha.git",
10
10
  "directory": "apps/cli"
11
11
  },
12
12
  "bugs": {
13
- "url": "https://gitea.lovekapibarasan.org/LoveKapibarasan/what-are-you-do-ing/issues"
13
+ "url": "https://github.com/what-are-you-do-ing/whatcha/issues"
14
14
  },
15
15
  "keywords": [
16
16
  "whatcha",