@aloth/olcli 0.14.0 → 0.15.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.
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Tracked changes: the insertions and deletions Overleaf records while track
3
+ * changes is on, shown as suggestions in the review panel.
4
+ *
5
+ * Pure functions only, for the same reason as `diff.ts` and `rename-plan.ts`:
6
+ * everything decided here is decided from the data a doc join returns, so it
7
+ * is unit-testable without an Overleaf account. The network side lives in
8
+ * `client.ts`.
9
+ *
10
+ * Two document formats exist, and they store tracked changes differently:
11
+ *
12
+ * - `sharejs-text-ot` docs carry `ranges.changes`, each
13
+ * `{ id, op: { i | d, p }, metadata: { user_id, ts } }`. `p` is an offset
14
+ * into the visible text. Tracked-deleted text is no longer in the doc at
15
+ * all; it survives only in `op.d`.
16
+ * - `history-ot` docs carry a StringFileData snapshot whose `content` still
17
+ * contains the tracked-deleted text, with `trackedChanges` given as
18
+ * `{ range: { pos, length }, tracking: { type, userId, ts } }` over that
19
+ * content. The server assigns these no ids. The Overleaf editor derives
20
+ * `change-<type>-<visible position>` and this module does the same, so the
21
+ * ids are only stable until the doc is next edited.
22
+ *
23
+ * Positions reported by this module are always offsets into the visible text,
24
+ * which is what the editor shows and what `olcli pull` downloads, so a
25
+ * position means the same thing for both formats.
26
+ */
27
+ export type TrackedChangeKind = 'insert' | 'delete';
28
+ /** One tracked change as stored in a single doc, before any project context is added. */
29
+ export interface DocTrackedChange {
30
+ id: string;
31
+ kind: TrackedChangeKind;
32
+ /** Offset into the visible text, tracked deletes excluded. */
33
+ position: number;
34
+ /** Inserted text for an insert, removed text for a delete. */
35
+ text: string;
36
+ /** Null when Overleaf recorded no user, e.g. edits written by a sync integration. */
37
+ userId: string | null;
38
+ timestamp?: string;
39
+ }
40
+ export interface TrackedChangeAuthor {
41
+ id: string | null;
42
+ name?: string;
43
+ email?: string;
44
+ }
45
+ export interface ReviewUser {
46
+ id: string;
47
+ email?: string;
48
+ first_name?: string;
49
+ last_name?: string;
50
+ }
51
+ /** A ShareJS text op component, the format `applyOtUpdate` takes for sharejs-text-ot docs. */
52
+ export interface ShareJsTextOp {
53
+ p: number;
54
+ i?: string;
55
+ d?: string;
56
+ /**
57
+ * Marks the op as an undo. The ranges tracker uses it to recognize an
58
+ * insertion that restores a tracked deletion and drop that deletion,
59
+ * rather than shift it along as if new text had been typed in front of it.
60
+ * The Overleaf editor sets it on every op it sends to reject a change.
61
+ */
62
+ u?: boolean;
63
+ }
64
+ /**
65
+ * Read `ranges.changes` of a sharejs-text-ot doc. The texts must already be
66
+ * decoded: with `encodeRanges` the join sends `op.i` and `op.d` as UTF-8
67
+ * bytes in a binary string, exactly like the doc lines.
68
+ *
69
+ * Order is preserved. It is the ranges tracker's order, which `planRejection`
70
+ * relies on to order changes that share a position.
71
+ */
72
+ export declare function parseShareJsChanges(ranges: any): DocTrackedChange[];
73
+ /**
74
+ * Read the tracked changes of a history-ot snapshot and compute the visible
75
+ * text. Mirrors `buildRangesFromSnapshot` in the Overleaf web frontend,
76
+ * including how it derives change ids.
77
+ */
78
+ export declare function parseHistoryOtChanges(snapshot: any): {
79
+ changes: DocTrackedChange[];
80
+ visibleContent: string;
81
+ };
82
+ export declare class RejectConflictError extends Error {
83
+ constructor(message: string);
84
+ }
85
+ /**
86
+ * Build the ops that reject `changes` in a sharejs-text-ot doc whose visible
87
+ * text is `content`: a tracked insertion is removed, a tracked deletion is
88
+ * put back. Returns the ops in the order they must be sent and the text they
89
+ * produce.
90
+ *
91
+ * `changes` must be in the ranges tracker's order (a filter of
92
+ * `parseShareJsChanges` output keeps it).
93
+ *
94
+ * The ops are applied one after another, each to the result of the previous
95
+ * one, so they run from the highest position to the lowest: undoing a change
96
+ * then never moves a change that has yet to be undone. That is the ordering
97
+ * the Overleaf editor uses, and its own comment explains the failure it
98
+ * prevents. A word replaced as "foo bar baz" -> "foo quux baz" is a tracked
99
+ * insertion of "quux" at 4 and a tracked deletion of "bar" at 8. Removing
100
+ * "quux" first and then restoring "bar" at 8 gives "foo bazbar"; restoring
101
+ * "bar" first gives "foo quuxbar baz", and removing "quux" then gives
102
+ * "foo bar baz".
103
+ *
104
+ * Changes at the same position run in reverse tracker order. The tracker
105
+ * keeps a deletion ahead of an insertion at the same offset, so the
106
+ * insertion is removed before the deleted text is put back in front of
107
+ * where it was, and several deletions at one offset are restored last one
108
+ * first, which leaves them in their original order.
109
+ *
110
+ * Every step is checked against the text it applies to, exactly as the
111
+ * server checks a delete op. A change that no longer matches throws
112
+ * `RejectConflictError` and nothing is returned, so a stale or overlapping
113
+ * selection fails here instead of on the server or, worse, removing the
114
+ * wrong text.
115
+ */
116
+ export declare function planRejection(content: string, changes: DocTrackedChange[]): {
117
+ ops: ShareJsTextOp[];
118
+ content: string;
119
+ };
120
+ /**
121
+ * Apply ShareJS text ops the way the server's text type does, one component
122
+ * after another, refusing a delete whose text does not match.
123
+ */
124
+ export declare function applyTextOps(content: string, ops: ShareJsTextOp[]): string;
125
+ /**
126
+ * Map user ids to people. Project owner and members come from the project
127
+ * itself; `changesUsers` (GET /project/<id>/changes/users) adds people who
128
+ * made changes but are no longer members. Members win on conflict, the same
129
+ * precedence the Overleaf editor uses.
130
+ */
131
+ export declare function buildUserDirectory(project: any, changesUsers?: unknown[]): Map<string, ReviewUser>;
132
+ export declare function describeAuthor(userId: string | null, users: Map<string, ReviewUser>): TrackedChangeAuthor;
133
+ export declare function formatAuthor(author: TrackedChangeAuthor): string;
134
+ /** Unified diff of a doc before and after a rejection, for the preview. */
135
+ export declare function renderRejectionDiff(path: string, before: string, after: string): string;
136
+ //# sourceMappingURL=tracked-changes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracked-changes.d.ts","sourceRoot":"","sources":["../src/tracked-changes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8FAA8F;AAC9F,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,CAAC,CAAC,EAAE,OAAO,CAAC;CACb;AAWD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG,GAAG,gBAAgB,EAAE,CAcnE;AAaD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,GAAG,GAAG;IAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAyC5G;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAOD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG;IAAE,GAAG,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA4BrH;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,MAAM,CAgB1E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,GAAE,OAAO,EAAO,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAetG;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,mBAAmB,CAUzG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAGhE;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvF"}
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Tracked changes: the insertions and deletions Overleaf records while track
3
+ * changes is on, shown as suggestions in the review panel.
4
+ *
5
+ * Pure functions only, for the same reason as `diff.ts` and `rename-plan.ts`:
6
+ * everything decided here is decided from the data a doc join returns, so it
7
+ * is unit-testable without an Overleaf account. The network side lives in
8
+ * `client.ts`.
9
+ *
10
+ * Two document formats exist, and they store tracked changes differently:
11
+ *
12
+ * - `sharejs-text-ot` docs carry `ranges.changes`, each
13
+ * `{ id, op: { i | d, p }, metadata: { user_id, ts } }`. `p` is an offset
14
+ * into the visible text. Tracked-deleted text is no longer in the doc at
15
+ * all; it survives only in `op.d`.
16
+ * - `history-ot` docs carry a StringFileData snapshot whose `content` still
17
+ * contains the tracked-deleted text, with `trackedChanges` given as
18
+ * `{ range: { pos, length }, tracking: { type, userId, ts } }` over that
19
+ * content. The server assigns these no ids. The Overleaf editor derives
20
+ * `change-<type>-<visible position>` and this module does the same, so the
21
+ * ids are only stable until the doc is next edited.
22
+ *
23
+ * Positions reported by this module are always offsets into the visible text,
24
+ * which is what the editor shows and what `olcli pull` downloads, so a
25
+ * position means the same thing for both formats.
26
+ */
27
+ import { createTwoFilesPatch } from 'diff';
28
+ function normalizeTimestamp(value) {
29
+ if (typeof value === 'string')
30
+ return value;
31
+ if (typeof value === 'number' || value instanceof Date) {
32
+ const date = new Date(value);
33
+ return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
34
+ }
35
+ return undefined;
36
+ }
37
+ /**
38
+ * Read `ranges.changes` of a sharejs-text-ot doc. The texts must already be
39
+ * decoded: with `encodeRanges` the join sends `op.i` and `op.d` as UTF-8
40
+ * bytes in a binary string, exactly like the doc lines.
41
+ *
42
+ * Order is preserved. It is the ranges tracker's order, which `planRejection`
43
+ * relies on to order changes that share a position.
44
+ */
45
+ export function parseShareJsChanges(ranges) {
46
+ const changes = [];
47
+ for (const change of ranges?.changes ?? []) {
48
+ const op = change?.op;
49
+ if (typeof change?.id !== 'string' || !op || typeof op.p !== 'number')
50
+ continue;
51
+ const userId = typeof change.metadata?.user_id === 'string' ? change.metadata.user_id : null;
52
+ const timestamp = normalizeTimestamp(change.metadata?.ts);
53
+ if (typeof op.i === 'string') {
54
+ changes.push({ id: change.id, kind: 'insert', position: op.p, text: op.i, userId, timestamp });
55
+ }
56
+ else if (typeof op.d === 'string') {
57
+ changes.push({ id: change.id, kind: 'delete', position: op.p, text: op.d, userId, timestamp });
58
+ }
59
+ }
60
+ return changes;
61
+ }
62
+ function isHistoryOtTrackedChange(value) {
63
+ return typeof value?.range?.pos === 'number'
64
+ && typeof value?.range?.length === 'number'
65
+ && (value?.tracking?.type === 'insert' || value?.tracking?.type === 'delete');
66
+ }
67
+ /**
68
+ * Read the tracked changes of a history-ot snapshot and compute the visible
69
+ * text. Mirrors `buildRangesFromSnapshot` in the Overleaf web frontend,
70
+ * including how it derives change ids.
71
+ */
72
+ export function parseHistoryOtChanges(snapshot) {
73
+ const content = typeof snapshot?.content === 'string' ? snapshot.content : '';
74
+ const tracked = (snapshot?.trackedChanges ?? [])
75
+ .filter(isHistoryOtTrackedChange)
76
+ .sort((a, b) => a.range.pos - b.range.pos);
77
+ const deletes = tracked.filter(change => change.tracking.type === 'delete');
78
+ // A snapshot position inside or after a tracked delete moves back by the
79
+ // part of that delete in front of it; inside one it lands on its start.
80
+ const toVisible = (pos) => {
81
+ let shift = 0;
82
+ for (const change of deletes) {
83
+ if (change.range.pos >= pos)
84
+ break;
85
+ shift += Math.min(change.range.pos + change.range.length, pos) - change.range.pos;
86
+ }
87
+ return pos - shift;
88
+ };
89
+ let visibleContent = '';
90
+ let cursor = 0;
91
+ for (const change of deletes) {
92
+ if (change.range.pos < cursor)
93
+ continue;
94
+ visibleContent += content.slice(cursor, change.range.pos);
95
+ cursor = change.range.pos + change.range.length;
96
+ }
97
+ visibleContent += content.slice(cursor);
98
+ const changes = tracked.map(change => {
99
+ const position = toVisible(change.range.pos);
100
+ const kind = change.tracking.type;
101
+ return {
102
+ id: `change-${kind}-${position}`,
103
+ kind,
104
+ position,
105
+ text: content.slice(change.range.pos, change.range.pos + change.range.length),
106
+ userId: typeof change.tracking.userId === 'string' ? change.tracking.userId : null,
107
+ timestamp: normalizeTimestamp(change.tracking.ts)
108
+ };
109
+ });
110
+ return { changes, visibleContent };
111
+ }
112
+ export class RejectConflictError extends Error {
113
+ constructor(message) {
114
+ super(message);
115
+ this.name = 'RejectConflictError';
116
+ }
117
+ }
118
+ function quote(text, max = 60) {
119
+ const shown = text.length > max ? `${text.slice(0, max)}...` : text;
120
+ return JSON.stringify(shown);
121
+ }
122
+ /**
123
+ * Build the ops that reject `changes` in a sharejs-text-ot doc whose visible
124
+ * text is `content`: a tracked insertion is removed, a tracked deletion is
125
+ * put back. Returns the ops in the order they must be sent and the text they
126
+ * produce.
127
+ *
128
+ * `changes` must be in the ranges tracker's order (a filter of
129
+ * `parseShareJsChanges` output keeps it).
130
+ *
131
+ * The ops are applied one after another, each to the result of the previous
132
+ * one, so they run from the highest position to the lowest: undoing a change
133
+ * then never moves a change that has yet to be undone. That is the ordering
134
+ * the Overleaf editor uses, and its own comment explains the failure it
135
+ * prevents. A word replaced as "foo bar baz" -> "foo quux baz" is a tracked
136
+ * insertion of "quux" at 4 and a tracked deletion of "bar" at 8. Removing
137
+ * "quux" first and then restoring "bar" at 8 gives "foo bazbar"; restoring
138
+ * "bar" first gives "foo quuxbar baz", and removing "quux" then gives
139
+ * "foo bar baz".
140
+ *
141
+ * Changes at the same position run in reverse tracker order. The tracker
142
+ * keeps a deletion ahead of an insertion at the same offset, so the
143
+ * insertion is removed before the deleted text is put back in front of
144
+ * where it was, and several deletions at one offset are restored last one
145
+ * first, which leaves them in their original order.
146
+ *
147
+ * Every step is checked against the text it applies to, exactly as the
148
+ * server checks a delete op. A change that no longer matches throws
149
+ * `RejectConflictError` and nothing is returned, so a stale or overlapping
150
+ * selection fails here instead of on the server or, worse, removing the
151
+ * wrong text.
152
+ */
153
+ export function planRejection(content, changes) {
154
+ const ordered = changes
155
+ .map((change, index) => ({ change, index }))
156
+ .sort((a, b) => b.change.position - a.change.position || b.index - a.index);
157
+ let text = content;
158
+ const ops = [];
159
+ for (const { change } of ordered) {
160
+ const { position } = change;
161
+ if (position < 0 || position > text.length) {
162
+ throw new RejectConflictError(`Tracked change ${change.id} points at position ${position}, outside the document (length ${text.length})`);
163
+ }
164
+ if (change.kind === 'insert') {
165
+ const found = text.slice(position, position + change.text.length);
166
+ if (found !== change.text) {
167
+ throw new RejectConflictError(`Tracked change ${change.id} no longer matches the document: expected ${quote(change.text)} at position ${position}, found ${quote(found)}. If it overlaps another selected change, reject them one at a time`);
168
+ }
169
+ ops.push({ p: position, d: change.text, u: true });
170
+ text = text.slice(0, position) + text.slice(position + change.text.length);
171
+ }
172
+ else {
173
+ ops.push({ p: position, i: change.text, u: true });
174
+ text = text.slice(0, position) + change.text + text.slice(position);
175
+ }
176
+ }
177
+ return { ops, content: text };
178
+ }
179
+ /**
180
+ * Apply ShareJS text ops the way the server's text type does, one component
181
+ * after another, refusing a delete whose text does not match.
182
+ */
183
+ export function applyTextOps(content, ops) {
184
+ let text = content;
185
+ for (const op of ops) {
186
+ if (typeof op.i === 'string') {
187
+ text = text.slice(0, op.p) + op.i + text.slice(op.p);
188
+ }
189
+ else if (typeof op.d === 'string') {
190
+ const deleted = text.slice(op.p, op.p + op.d.length);
191
+ if (deleted !== op.d) {
192
+ throw new Error(`Delete component '${op.d}' does not match deleted text '${deleted}'`);
193
+ }
194
+ text = text.slice(0, op.p) + text.slice(op.p + op.d.length);
195
+ }
196
+ else {
197
+ throw new Error('Unknown op type');
198
+ }
199
+ }
200
+ return text;
201
+ }
202
+ /**
203
+ * Map user ids to people. Project owner and members come from the project
204
+ * itself; `changesUsers` (GET /project/<id>/changes/users) adds people who
205
+ * made changes but are no longer members. Members win on conflict, the same
206
+ * precedence the Overleaf editor uses.
207
+ */
208
+ export function buildUserDirectory(project, changesUsers = []) {
209
+ const users = new Map();
210
+ const add = (user, id) => {
211
+ if (typeof id !== 'string' || !id)
212
+ return;
213
+ users.set(id, {
214
+ id,
215
+ email: typeof user?.email === 'string' ? user.email : undefined,
216
+ first_name: typeof user?.first_name === 'string' ? user.first_name : undefined,
217
+ last_name: typeof user?.last_name === 'string' ? user.last_name : undefined
218
+ });
219
+ };
220
+ for (const user of changesUsers)
221
+ add(user, user?.id ?? user?._id);
222
+ if (project?.owner)
223
+ add(project.owner, project.owner._id ?? project.owner.id);
224
+ for (const member of project?.members ?? [])
225
+ add(member, member?._id ?? member?.id);
226
+ return users;
227
+ }
228
+ export function describeAuthor(userId, users) {
229
+ if (!userId)
230
+ return { id: null };
231
+ const user = users.get(userId);
232
+ if (!user)
233
+ return { id: userId };
234
+ const name = [user.first_name, user.last_name].filter(Boolean).join(' ').trim();
235
+ return {
236
+ id: userId,
237
+ ...(name ? { name } : {}),
238
+ ...(user.email ? { email: user.email } : {})
239
+ };
240
+ }
241
+ export function formatAuthor(author) {
242
+ if (author.name && author.email)
243
+ return `${author.name} <${author.email}>`;
244
+ return author.name || author.email || author.id || 'unknown user';
245
+ }
246
+ /** Unified diff of a doc before and after a rejection, for the preview. */
247
+ export function renderRejectionDiff(path, before, after) {
248
+ return createTwoFilesPatch(`a/${path}`, `b/${path}`, before, after, undefined, undefined, { context: 2 });
249
+ }
250
+ //# sourceMappingURL=tracked-changes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracked-changes.js","sourceRoot":"","sources":["../src/tracked-changes.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aloth/olcli",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "Command-line interface for Overleaf — Sync, manage, and compile LaTeX projects from your terminal",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",