@adobe/helix-google-support 1.1.0 → 1.2.2

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [1.2.2](https://github.com/adobe/helix-google-support/compare/v1.2.1...v1.2.2) (2022-04-28)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * include mimeType ([#11](https://github.com/adobe/helix-google-support/issues/11)) ([67ab999](https://github.com/adobe/helix-google-support/commit/67ab999a7fee111978a15c4393761e4b614ee2fc))
7
+
8
+ ## [1.2.1](https://github.com/adobe/helix-google-support/compare/v1.2.0...v1.2.1) (2022-04-28)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * include mimeType ([#10](https://github.com/adobe/helix-google-support/issues/10)) ([993e24a](https://github.com/adobe/helix-google-support/commit/993e24acdd723402a6d85a8bf74e3b93df8c5d0e))
14
+
15
+ # [1.2.0](https://github.com/adobe/helix-google-support/compare/v1.1.0...v1.2.0) (2022-04-28)
16
+
17
+
18
+ ### Features
19
+
20
+ * add get file|doc from path ([#9](https://github.com/adobe/helix-google-support/issues/9)) ([4a2e927](https://github.com/adobe/helix-google-support/commit/4a2e9272f4328e936e65b7144d04e516ac602625))
21
+
1
22
  # [1.1.0](https://github.com/adobe/helix-google-support/compare/v1.0.1...v1.1.0) (2022-04-28)
2
23
 
3
24
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-google-support",
3
- "version": "1.1.0",
3
+ "version": "1.2.2",
4
4
  "description": "Helix Google Support",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -0,0 +1,140 @@
1
+ /*
2
+ * Copyright 2022 Adobe. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+ declare interface ICachePlugin {}
13
+
14
+ declare interface DriveItemInfo {}
15
+
16
+ declare interface GoogleClientOptions {
17
+ log:Console;
18
+ clientId:string;
19
+ clientSecret:string;
20
+ redirectUri:string;
21
+ cachePlugin?:ICachePlugin;
22
+ }
23
+
24
+ /**
25
+ * Google client
26
+ */
27
+ declare class GoogleClient {
28
+ /**
29
+ * Sets the global item cache options. It internally creates a new LRU
30
+ * with the given options
31
+ *
32
+ * @param opts
33
+ */
34
+ static setItemCacheOptions(opts:object);
35
+
36
+ /**
37
+ * Returns a url for a google drive id.
38
+ * @param {string} id
39
+ * @returns {string}
40
+ */
41
+ static id2Url(id:string):string;
42
+
43
+ constructor(opts:GoogleClientOptions);
44
+
45
+ init():Promise<GoogleClient>;
46
+
47
+ generateAuthUrl(...args):Promise<string>;
48
+
49
+ /**
50
+ * Sets the credentials
51
+ * @param tokens
52
+ * @returns {Promise<void>}
53
+ */
54
+ setCredentials(tokens:object):Promise<void>;
55
+
56
+ /**
57
+ * Returns the token for the given code
58
+ * @param {string} code
59
+ * @returns {Promise<*>}
60
+ */
61
+ getToken(code:string):Promise<object>;
62
+
63
+ /**
64
+ * @param {string} parentId
65
+ * @param {string[]} pathSegments
66
+ * @param {string} parentPath
67
+ * @returns {Promise<DriveItemInfo[]>|null}
68
+ */
69
+ getUncachedItemsFromSegments(parentId:string, pathSegments:string[], parentPath:string):Promise<DriveItemInfo[]>;
70
+
71
+ /**
72
+ * @param {string} parentId
73
+ * @param {string} pathSegments
74
+ * @param {string} parentPath
75
+ * @returns {Promise<DriveItemInfo[]>|null}
76
+ */
77
+ getDriveItemsFromSegments(parentId:string, pathSegments:string[], parentPath:string):Promise<DriveItemInfo[]>;
78
+
79
+ /**
80
+ * returns the items hierarchy for the given path and root id, starting with the given path.
81
+ * @param {string} parentId
82
+ * @param {string} path
83
+ * @return {DriveItemInfo[]}
84
+ */
85
+ getDriveItemsFromSegments(parentId:string, path:string):Promise<DriveItemInfo[]>;
86
+
87
+ /**
88
+ * returns the items hierarchy for the given item, starting with the given id
89
+ * @param {string} fileId
90
+ * @param {object} roots
91
+ * @returns {Promise<DriveItemInfo[]>}
92
+ */
93
+ getItemsFromId(fileId:string, roots:object):Promise<DriveItemInfo[]>;
94
+
95
+ /**
96
+ * Returns the (cached) item for the given path or {@code null} if the item cannot be found.
97
+ * The item will contains a `invalidate()` method which can be used to remove it from the cache.
98
+ *
99
+ * @param {string} parentId
100
+ * @param {string} path
101
+ * @returns {Promise<DriveItemInfo>}
102
+ */
103
+ getItemFromPath(parentId:string, path:string):Promise<DriveItemInfo>;
104
+
105
+ /**
106
+ * Returns an (uncached) file directly via the google api
107
+ * @param {string} fileId
108
+ * @returns {string} file data
109
+ */
110
+ getFile(fileId:string):Promise<string>;
111
+
112
+ /**
113
+ * Fetches the file data from the give path. If the file with the internal id could not be
114
+ * fetched, the item cache is invalidated and the operation is retried. this is to support
115
+ * moved items.
116
+ * @param {string} parentId
117
+ * @param {string} path
118
+ * @param {boolean} noRetry {@code true} to avoid retry
119
+ * @returns {Promise<string>|null} The data of the file or {@code null} if the file does not exist
120
+ */
121
+ getFileFromPath(parentId:string, path:string, noRetry:boolean):Promise<string>;
122
+
123
+ /**
124
+ * Returns an (uncached) document directly via the google api
125
+ * @param {string} documentId
126
+ * @returns {object} document
127
+ */
128
+ getDocument(documentId:string):Promise<object>;
129
+
130
+ /**
131
+ * Fetches the document from the give path. If the document with the internal id could not be
132
+ * fetched, the item cache is invalidated and the operation is retried. this is to support
133
+ * moved items.
134
+ * @param {string} parentId
135
+ * @param {string} path
136
+ * @param {boolean} noRetry {@code true} to avoid retry
137
+ * @returns {Promise<object>|null} The document or {@code null} if the document does not exist
138
+ */
139
+ getDocumentFromPath(parentId:string, path:string, noRetry:boolean):Promise<object>;
140
+ }
@@ -150,12 +150,12 @@ export class GoogleClient {
150
150
  }
151
151
 
152
152
  /**
153
- * @param {string[]} pathSegments
154
153
  * @param {string} parentId
154
+ * @param {string[]} pathSegments
155
155
  * @param {string} parentPath
156
156
  * @returns {Promise<DriveItemInfo[]>|null}
157
157
  */
158
- async getUncachedItemsFromSegments(pathSegments, parentId, parentPath) {
158
+ async getUncachedItemsFromSegments(parentId, pathSegments, parentPath) {
159
159
  const { log, drive } = this;
160
160
  const name = pathSegments.shift();
161
161
  const [baseName, ext] = splitByExtension(name);
@@ -169,7 +169,7 @@ export class GoogleClient {
169
169
  // folder if path continues, sheet otherwise
170
170
  `and mimeType ${pathSegments.length ? '=' : '!='} 'application/vnd.google-apps.folder'`,
171
171
  ].join(' '),
172
- fields: 'nextPageToken, files(id, name, modifiedTime)',
172
+ fields: 'nextPageToken, files(id, name, mimeType, modifiedTime)',
173
173
  includeItemsFromAllDrives: true,
174
174
  supportsAllDrives: true,
175
175
  pageSize: 1000,
@@ -226,7 +226,7 @@ export class GoogleClient {
226
226
  const itemPath = `${parentPath}/${sanitizedName}`;
227
227
  const children = pathSegments.length
228
228
  // eslint-disable-next-line no-use-before-define
229
- ? await this.getDriveItemsFromSegments(pathSegments, item.id, itemPath)
229
+ ? await this.getDriveItemsFromSegments(item.id, pathSegments, itemPath)
230
230
  : [];
231
231
 
232
232
  if (!children) {
@@ -236,6 +236,7 @@ export class GoogleClient {
236
236
  name,
237
237
  path: itemPath,
238
238
  id: item.id,
239
+ mimeType: item.mimeType,
239
240
  }, item);
240
241
 
241
242
  if (children.length) {
@@ -250,18 +251,18 @@ export class GoogleClient {
250
251
  }
251
252
 
252
253
  /**
253
- * @param {string} pathSegments
254
254
  * @param {string} parentId
255
+ * @param {string} pathSegments
255
256
  * @param {string} parentPath
256
257
  * @returns {Promise<DriveItemInfo[]>|null}
257
258
  */
258
- async getDriveItemsFromSegments(pathSegments, parentId, parentPath) {
259
+ async getDriveItemsFromSegments(parentId, pathSegments, parentPath) {
259
260
  const key = getCacheKey(parentId, pathSegments);
260
261
  let items = lru.get(key);
261
262
  if (items) {
262
263
  return items;
263
264
  }
264
- items = await this.getUncachedItemsFromSegments(pathSegments, parentId, parentPath);
265
+ items = await this.getUncachedItemsFromSegments(parentId, pathSegments, parentPath);
265
266
  if (items) {
266
267
  lru.set(key, items);
267
268
  // add invalidation function as not-enumerable to keep compatible objects
@@ -278,20 +279,21 @@ export class GoogleClient {
278
279
 
279
280
  /**
280
281
  * returns the items hierarchy for the given path and root id, starting with the given path.
281
- * @param path
282
- * @param rootId
282
+ * @param {string} parentId
283
+ * @param {string} path
283
284
  * @return {DriveItemInfo[]}
284
285
  */
285
- async getItemsFromPath(path, rootId) {
286
+ async getItemsFromPath(parentId, path) {
286
287
  const segs = createPathSegments(path);
287
- const result = await this.getDriveItemsFromSegments(segs, rootId, '');
288
+ const result = await this.getDriveItemsFromSegments(parentId, segs, '');
288
289
  if (!result) {
289
290
  return [];
290
291
  }
291
292
  return [...result, {
292
293
  name: '',
293
294
  path: '/',
294
- id: rootId,
295
+ id: parentId,
296
+ mimeType: 'application/vnd.google-apps.folder',
295
297
  }];
296
298
  }
297
299
 
@@ -299,6 +301,7 @@ export class GoogleClient {
299
301
  * returns the items hierarchy for the given item, starting with the given id
300
302
  * @param {string} fileId
301
303
  * @param {object} roots
304
+ * @private
302
305
  * @returns {Promise<DriveItemInfo[]>}
303
306
  */
304
307
  async getItems(fileId, roots) {
@@ -366,13 +369,13 @@ export class GoogleClient {
366
369
  * Returns the (cached) item for the given path or {@code null} if the item cannot be found.
367
370
  * The item will contains a `invalidate()` method which can be used to remove it from the cache.
368
371
  *
369
- * @param {string} rootId
372
+ * @param {string} parentId
370
373
  * @param {string} path
371
374
  * @returns {Promise<DriveItemInfo>}
372
375
  */
373
- async getItemFromPath(rootId, path) {
376
+ async getItemFromPath(parentId, path) {
374
377
  const segs = createPathSegments(path);
375
- const items = await this.getDriveItemsFromSegments(segs, rootId, '');
378
+ const items = await this.getDriveItemsFromSegments(parentId, segs, '');
376
379
  const item = items?.[0];
377
380
  if (!item) {
378
381
  return null;
@@ -400,6 +403,37 @@ export class GoogleClient {
400
403
  }
401
404
  }
402
405
 
406
+ /**
407
+ * Fetches the file data from the give path. If the file with the internal id could not be
408
+ * fetched, the item cache is invalidated and the operation is retried. this is to support
409
+ * moved items.
410
+ * @param {string} parentId
411
+ * @param {string} path
412
+ * @param {boolean} noRetry {@code true} to avoid retry
413
+ * @returns {Promise<string>|null} The data of the file or {@code null} if the file does not exist
414
+ */
415
+ async getFileFromPath(parentId, path, noRetry) {
416
+ const item = await this.getItemFromPath(parentId, path);
417
+ if (!item) {
418
+ return null;
419
+ }
420
+ try {
421
+ // noinspection ES6RedundantAwait (need to catch exception)
422
+ return await this.getFile(item.id);
423
+ } catch (e) {
424
+ if (e.statusCode === 404) {
425
+ if (noRetry) {
426
+ return null;
427
+ }
428
+ this.log.info(`file ${item.id} does not exist - invalidating cache and retry`);
429
+ item.invalidate();
430
+ return this.getFileFromPath(parentId, path, true);
431
+ } else {
432
+ throw e;
433
+ }
434
+ }
435
+ }
436
+
403
437
  /**
404
438
  * Returns an (uncached) document directly via the google api
405
439
  * @param {string} documentId
@@ -420,4 +454,35 @@ export class GoogleClient {
420
454
  throw e;
421
455
  }
422
456
  }
457
+
458
+ /**
459
+ * Fetches the document from the give path. If the document with the internal id could not be
460
+ * fetched, the item cache is invalidated and the operation is retried. this is to support
461
+ * moved items.
462
+ * @param {string} parentId
463
+ * @param {string} path
464
+ * @param {boolean} noRetry {@code true} to avoid retry
465
+ * @returns {Promise<object>|null} The document or {@code null} if the document does not exist
466
+ */
467
+ async getDocumentFromPath(parentId, path, noRetry) {
468
+ const item = await this.getItemFromPath(parentId, path);
469
+ if (!item) {
470
+ return null;
471
+ }
472
+ try {
473
+ // noinspection ES6RedundantAwait (need to catch exception)
474
+ return await this.getDocument(item.id);
475
+ } catch (e) {
476
+ if (e.statusCode === 404) {
477
+ if (noRetry) {
478
+ return null;
479
+ }
480
+ this.log.info(`document ${item.id} does not exist - invalidating cache and retry`);
481
+ item.invalidate();
482
+ return this.getDocumentFromPath(parentId, path, true);
483
+ } else {
484
+ throw e;
485
+ }
486
+ }
487
+ }
423
488
  }