@link-assistant/web-capture 1.7.5 → 1.7.6

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.
@@ -3,7 +3,13 @@ import {
3
3
  isGoogleDocsUrl,
4
4
  extractDocumentId,
5
5
  buildExportUrl,
6
+ buildEditUrl,
7
+ buildDocsApiUrl,
6
8
  extractBase64Images,
9
+ parseGoogleDocsModelChunks,
10
+ renderGoogleDocsCapture,
11
+ renderDocsApiDocument,
12
+ selectGoogleDocsCaptureMethod,
7
13
  GDOCS_EXPORT_FORMATS,
8
14
  } from '../../src/gdocs.js';
9
15
  import {
@@ -149,6 +155,161 @@ describe('gdocs', () => {
149
155
  });
150
156
  });
151
157
 
158
+ describe('capture method selection (issue #72)', () => {
159
+ it('honors explicit browser capture for Google Docs URLs', () => {
160
+ expect(selectGoogleDocsCaptureMethod('browser')).toBe('browser-model');
161
+ });
162
+
163
+ it('uses public export for API capture without token', () => {
164
+ expect(selectGoogleDocsCaptureMethod('api')).toBe('public-export');
165
+ });
166
+
167
+ it('uses Docs REST API for API capture with token', () => {
168
+ expect(selectGoogleDocsCaptureMethod('api', 'token-123')).toBe(
169
+ 'docs-api'
170
+ );
171
+ });
172
+ });
173
+
174
+ describe('buildEditUrl', () => {
175
+ it('builds the fresh Google Docs editor URL', () => {
176
+ expect(buildEditUrl('abc123')).toBe(
177
+ 'https://docs.google.com/document/d/abc123/edit'
178
+ );
179
+ });
180
+ });
181
+
182
+ describe('buildDocsApiUrl', () => {
183
+ it('builds the Google Docs REST API URL', () => {
184
+ expect(buildDocsApiUrl('abc123')).toBe(
185
+ 'https://docs.googleapis.com/v1/documents/abc123'
186
+ );
187
+ });
188
+ });
189
+
190
+ describe('parseGoogleDocsModelChunks (issue #72)', () => {
191
+ it('includes regular and suggested text from DOCS_modelChunk data', () => {
192
+ const capture = parseGoogleDocsModelChunks([
193
+ {
194
+ chunk: [
195
+ { ty: 'is', s: 'Stable ' },
196
+ { ty: 'iss', s: 'suggested\n' },
197
+ ],
198
+ },
199
+ ]);
200
+
201
+ expect(capture.text).toContain('Stable suggested');
202
+ expect(renderGoogleDocsCapture(capture, 'markdown')).toContain(
203
+ 'Stable suggested'
204
+ );
205
+ });
206
+
207
+ it('extracts table cells and suggested images from DOCS_modelChunk data', () => {
208
+ const chunks = [
209
+ {
210
+ chunk: [
211
+ { ty: 'is', s: String.fromCharCode(0x10) },
212
+ { ty: 'is', s: String.fromCharCode(0x12) },
213
+ { ty: 'is', s: String.fromCharCode(0x1c) },
214
+ { ty: 'is', s: 'Cell A' },
215
+ { ty: 'is', s: String.fromCharCode(0x1c) },
216
+ { ty: 'is', s: '*' },
217
+ { ty: 'is', s: '\n' },
218
+ { ty: 'is', s: String.fromCharCode(0x11) },
219
+ {
220
+ ty: 'ase',
221
+ id: 'suggested-image',
222
+ epm: { ee_eo: { i_cid: 'cid_12345678901234567890' } },
223
+ },
224
+ { ty: 'ste', id: 'suggested-image', spi: 10 },
225
+ ],
226
+ },
227
+ ];
228
+ const capture = parseGoogleDocsModelChunks(chunks, {
229
+ cid_12345678901234567890:
230
+ 'https://docs.google.com/docs-images-rt/image-id',
231
+ });
232
+ const markdown = renderGoogleDocsCapture(capture, 'markdown');
233
+
234
+ expect(capture.tables).toHaveLength(1);
235
+ expect(capture.tables[0].rows[0].cells).toHaveLength(2);
236
+ expect(markdown).toContain('Cell A');
237
+ expect(markdown).toContain(
238
+ '![suggested image](https://docs.google.com/docs-images-rt/image-id)'
239
+ );
240
+ });
241
+ });
242
+
243
+ describe('renderDocsApiDocument (issue #72)', () => {
244
+ it('renders Google Docs REST API paragraphs, tables, and inline images', () => {
245
+ const apiDocument = {
246
+ title: 'API Doc',
247
+ body: {
248
+ content: [
249
+ {
250
+ paragraph: {
251
+ elements: [{ textRun: { content: 'Intro paragraph\n' } }],
252
+ },
253
+ },
254
+ {
255
+ table: {
256
+ tableRows: [
257
+ {
258
+ tableCells: [
259
+ {
260
+ content: [
261
+ {
262
+ paragraph: {
263
+ elements: [{ textRun: { content: 'Name\n' } }],
264
+ },
265
+ },
266
+ ],
267
+ },
268
+ {
269
+ content: [
270
+ {
271
+ paragraph: {
272
+ elements: [
273
+ {
274
+ inlineObjectElement: {
275
+ inlineObjectId: 'image-1',
276
+ },
277
+ },
278
+ ],
279
+ },
280
+ },
281
+ ],
282
+ },
283
+ ],
284
+ },
285
+ ],
286
+ },
287
+ },
288
+ ],
289
+ },
290
+ inlineObjects: {
291
+ 'image-1': {
292
+ inlineObjectProperties: {
293
+ embeddedObject: {
294
+ title: 'Diagram',
295
+ imageProperties: {
296
+ contentUri: 'https://example.com/diagram.png',
297
+ },
298
+ },
299
+ },
300
+ },
301
+ },
302
+ };
303
+
304
+ const rendered = renderDocsApiDocument(apiDocument);
305
+
306
+ expect(rendered.markdown).toContain('Intro paragraph');
307
+ expect(rendered.markdown).toContain('| Name | ![Diagram]');
308
+ expect(rendered.html).toContain('<table>');
309
+ expect(rendered.html).toContain('src="https://example.com/diagram.png"');
310
+ });
311
+ });
312
+
152
313
  describe('GDOCS_EXPORT_FORMATS', () => {
153
314
  it('contains all expected formats', () => {
154
315
  expect(GDOCS_EXPORT_FORMATS).toEqual({