@adobe/helix-onedrive-support 11.0.6 → 11.1.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [11.1.1](https://github.com/adobe/helix-onedrive-support/compare/v11.1.0...v11.1.1) (2023-11-03)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add interface for doFetch ([#464](https://github.com/adobe/helix-onedrive-support/issues/464)) ([43eb52d](https://github.com/adobe/helix-onedrive-support/commit/43eb52d8cde7ce1580dad3af8218032bc7d65ecc))
7
+
8
+ # [11.1.0](https://github.com/adobe/helix-onedrive-support/compare/v11.0.6...v11.1.0) (2023-10-31)
9
+
10
+
11
+ ### Features
12
+
13
+ * support for non-persistent sessions and table filtering ([bba88fc](https://github.com/adobe/helix-onedrive-support/commit/bba88fcc3150490436af2d0944ed54a5c5517502))
14
+
1
15
  ## [11.0.6](https://github.com/adobe/helix-onedrive-support/compare/v11.0.5...v11.0.6) (2023-10-31)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-onedrive-support",
3
- "version": "11.0.6",
3
+ "version": "11.1.1",
4
4
  "description": "Helix OneDrive Support",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Copyright 2023 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
+ export declare interface GraphAPI {
13
+ doFetch(relUrl: string, rawResponseBody: boolean, options: any): Promise<any>;
14
+ }
@@ -145,6 +145,18 @@ function handleTable(container, segs, method, body) {
145
145
  });
146
146
  return null;
147
147
  }
148
+ if ((segs.length >= 3) && (segs[1] === 'filter') && (segs[2] === 'apply')) {
149
+ if (table.filters) {
150
+ throw new Error('Only one filter at a time supported currently!');
151
+ }
152
+ const { criteria } = JSON.parse(body);
153
+ if (criteria.filterOn !== 'values') {
154
+ throw new Error('Only value based filtering supported currently!');
155
+ }
156
+ const colName = segs[0];
157
+ table.filters = { column: colName, criteria };
158
+ return null;
159
+ }
148
160
  if (body) {
149
161
  ({ name, index = table.headerNames.length } = body);
150
162
  table.headerNames.splice(index, 0, name);
@@ -180,11 +192,25 @@ function handleTable(container, segs, method, body) {
180
192
  };
181
193
  }
182
194
  case 'range': {
195
+ if ((segs.length >= 2) && (segs[0] === 'visibleView') && (segs[1] === 'rows')) {
196
+ const colIdx = table.filters ? table.headerNames.indexOf(table.filters.column) : -1;
197
+ const result = [{ cellAddresses: [[0]], values: [table.headerNames] }];
198
+ for (const [i, row] of table.rows.entries()) {
199
+ if ((!table.filters) || table.filters.criteria.values.includes(row[colIdx])) {
200
+ result.push({ cellAddresses: [[i + 1]], values: [row] });
201
+ }
202
+ }
203
+ return { value: result };
204
+ }
183
205
  return {
184
206
  address: 'sheet!A1:B10',
185
207
  addressLocal: 'A1:B10',
186
208
  };
187
209
  }
210
+ case 'clearFilters': {
211
+ table.filters = null;
212
+ return {};
213
+ }
188
214
  default:
189
215
  if (body) {
190
216
  table.name = body.name;
@@ -388,7 +414,7 @@ export class OneDriveMock extends OneDrive {
388
414
  }
389
415
  } else if (segs[0] === 'createSession') {
390
416
  return {
391
- id: 'test-session-id',
417
+ id: JSON.parse(body).persistChanges ? 'test-session-id' : 'test-non-persistent-session-id',
392
418
  };
393
419
  } else if (segs[0] === 'refreshSession' || segs[0] === 'closeSession') {
394
420
  return {};
@@ -12,12 +12,16 @@
12
12
  import { StatusCodeError } from '../StatusCodeError.js';
13
13
 
14
14
  export class NamedItemContainer {
15
- constructor(oneDrive) {
16
- this._oneDrive = oneDrive;
15
+ /**
16
+ * Create a new instance of this class.
17
+ * @param {import('../GraphAPI.js').GraphAPI} graphAPI graph API
18
+ */
19
+ constructor(graphAPI) {
20
+ this._graphAPI = graphAPI;
17
21
  }
18
22
 
19
23
  async getNamedItems() {
20
- const result = await this._oneDrive.doFetch(`${this.uri}/names`);
24
+ const result = await this._graphAPI.doFetch(`${this.uri}/names`);
21
25
  return result.value.map((v) => ({
22
26
  name: v.name,
23
27
  value: v.value,
@@ -28,7 +32,7 @@ export class NamedItemContainer {
28
32
  async getNamedItem(name) {
29
33
  try {
30
34
  // await result in order to be able to catch errors
31
- return await this._oneDrive.doFetch(`${this.uri}/names/${name}`);
35
+ return await this._graphAPI.doFetch(`${this.uri}/names/${name}`);
32
36
  } catch (e) {
33
37
  if (e.statusCode === 404) {
34
38
  return null;
@@ -40,7 +44,7 @@ export class NamedItemContainer {
40
44
  async addNamedItem(name, reference, comment) {
41
45
  try {
42
46
  // await result in order to be able to catch errors
43
- return await this._oneDrive.doFetch(`${this.uri}/names/add`, false, {
47
+ return await this._graphAPI.doFetch(`${this.uri}/names/add`, false, {
44
48
  method: 'POST',
45
49
  body: {
46
50
  name,
@@ -59,7 +63,7 @@ export class NamedItemContainer {
59
63
  async deleteNamedItem(name) {
60
64
  try {
61
65
  // await result in order to be able to catch errors
62
- return await this._oneDrive.doFetch(`${this.uri}/names/${name}`, true, {
66
+ return await this._graphAPI.doFetch(`${this.uri}/names/${name}`, true, {
63
67
  method: 'DELETE',
64
68
  });
65
69
  } catch (e) {
@@ -12,8 +12,14 @@
12
12
  import { superTrim } from '../utils.js';
13
13
 
14
14
  export class Range {
15
- constructor(oneDrive, uri, log) {
16
- this._oneDrive = oneDrive;
15
+ /**
16
+ * Create a new instance of this class.
17
+ * @param {import('../GraphAPI.js').GraphAPI} graphAPI graph API
18
+ * @param {string} uri URI of this range
19
+ * @param {any} log logger
20
+ */
21
+ constructor(graphAPI, uri, log) {
22
+ this._graphAPI = graphAPI;
17
23
  this._uri = uri;
18
24
  this._log = log;
19
25
  }
@@ -29,7 +35,7 @@ export class Range {
29
35
  async getData() {
30
36
  if (!this._data) {
31
37
  this.log.debug(`get range data from ${this.uri}`);
32
- this._data = await this._oneDrive.doFetch(this.uri);
38
+ this._data = await this._graphAPI.doFetch(this.uri);
33
39
  }
34
40
  return this._data;
35
41
  }
@@ -72,14 +78,14 @@ export class Range {
72
78
  } else {
73
79
  // optimization: ask for the values, only, not the complete range object
74
80
  this.log.debug(`get range values from ${this.uri}`);
75
- this._values = (await this._oneDrive.doFetch(`${this.uri}?$select=values`)).values;
81
+ this._values = (await this._graphAPI.doFetch(`${this.uri}?$select=values`)).values;
76
82
  }
77
83
  }
78
84
  return this._values;
79
85
  }
80
86
 
81
87
  async update(newValues) {
82
- const result = await this._oneDrive.doFetch(this.uri, false, {
88
+ const result = await this._graphAPI.doFetch(this.uri, false, {
83
89
  method: 'PATCH',
84
90
  body: newValues,
85
91
  });
@@ -87,7 +93,7 @@ export class Range {
87
93
  }
88
94
 
89
95
  async delete(shift = 'Up') {
90
- await this._oneDrive.doFetch(`${this.uri}/delete`, false, {
96
+ await this._graphAPI.doFetch(`${this.uri}/delete`, false, {
91
97
  method: 'POST',
92
98
  body: { shift },
93
99
  });
@@ -96,7 +102,7 @@ export class Range {
96
102
  }
97
103
 
98
104
  async insert(shift = 'Down') {
99
- const result = await this._oneDrive.doFetch(`${this.uri}/insert`, false, {
105
+ const result = await this._graphAPI.doFetch(`${this.uri}/insert`, false, {
100
106
  method: 'POST',
101
107
  body: { shift },
102
108
  });
@@ -13,8 +13,15 @@ import { superTrim } from '../utils.js';
13
13
  import { Range } from './Range.js';
14
14
 
15
15
  export class Table {
16
- constructor(oneDrive, prefix, name, log) {
17
- this._oneDrive = oneDrive;
16
+ /**
17
+ * Create a new instance of this class.
18
+ * @param {import('../GraphAPI.js').GraphAPI} graphAPI graph API
19
+ * @param {string} prefix URI prefix for this table
20
+ * @param {string} name table name
21
+ * @param {any} log logger
22
+ */
23
+ constructor(graphAPI, prefix, name, log) {
24
+ this._graphAPI = graphAPI;
18
25
  this._prefix = prefix;
19
26
  this._name = name;
20
27
  this._log = log;
@@ -22,7 +29,7 @@ export class Table {
22
29
 
23
30
  async rename(name) {
24
31
  // TODO: check name for allowed characters and length
25
- const result = await this._oneDrive.doFetch(this.uri, false, {
32
+ const result = await this._graphAPI.doFetch(this.uri, false, {
26
33
  method: 'PATCH',
27
34
  body: {
28
35
  name,
@@ -33,19 +40,19 @@ export class Table {
33
40
  }
34
41
 
35
42
  async getHeaderNames() {
36
- const result = await this._oneDrive.doFetch(`${this.uri}/headerRowRange`);
43
+ const result = await this._graphAPI.doFetch(`${this.uri}/headerRowRange`);
37
44
  return result.values[0];
38
45
  }
39
46
 
40
47
  async getRows() {
41
- const result = await this._oneDrive.doFetch(`${this.uri}/rows`);
48
+ const result = await this._graphAPI.doFetch(`${this.uri}/rows`);
42
49
  return result.value.map((v) => v.values[0]);
43
50
  }
44
51
 
45
52
  async getRowsAsObjects({ trim = false } = {}) {
46
53
  const { log } = this;
47
54
  this.log.debug(`get columns from ${this.uri}/columns`);
48
- const result = await this._oneDrive.doFetch(`${this.uri}/columns`);
55
+ const result = await this._graphAPI.doFetch(`${this.uri}/columns`);
49
56
  const columnNames = result.value.map(({ name }) => name);
50
57
  log.debug(`got column names: ${columnNames}`);
51
58
 
@@ -68,7 +75,7 @@ export class Table {
68
75
  }
69
76
 
70
77
  async getRow(index) {
71
- const result = await this._oneDrive.doFetch(`${this.uri}/rows/itemAt(index=${index})`);
78
+ const result = await this._graphAPI.doFetch(`${this.uri}/rows/itemAt(index=${index})`);
72
79
  return result.values[0];
73
80
  }
74
81
 
@@ -78,7 +85,7 @@ export class Table {
78
85
  }
79
86
 
80
87
  async addRows(values, index = null) {
81
- const result = await this._oneDrive.doFetch(`${this.uri}/rows/add`, false, {
88
+ const result = await this._graphAPI.doFetch(`${this.uri}/rows/add`, false, {
82
89
  method: 'POST',
83
90
  body: {
84
91
  index,
@@ -89,7 +96,7 @@ export class Table {
89
96
  }
90
97
 
91
98
  async replaceRow(index, values) {
92
- return this._oneDrive.doFetch(`${this.uri}/rows/itemAt(index=${index})`, false, {
99
+ return this._graphAPI.doFetch(`${this.uri}/rows/itemAt(index=${index})`, false, {
93
100
  method: 'PATCH',
94
101
  body: {
95
102
  values: [values],
@@ -98,18 +105,18 @@ export class Table {
98
105
  }
99
106
 
100
107
  async deleteRow(index) {
101
- return this._oneDrive.doFetch(`${this.uri}/rows/itemAt(index=${index})`, true, {
108
+ return this._graphAPI.doFetch(`${this.uri}/rows/itemAt(index=${index})`, true, {
102
109
  method: 'DELETE',
103
110
  });
104
111
  }
105
112
 
106
113
  async getRowCount() {
107
- const result = await this._oneDrive.doFetch(`${this.uri}/dataBodyRange?$select=rowCount`);
114
+ const result = await this._graphAPI.doFetch(`${this.uri}/dataBodyRange?$select=rowCount`);
108
115
  return result.rowCount;
109
116
  }
110
117
 
111
118
  async getColumn(name) {
112
- const result = await this._oneDrive.doFetch(`${this.uri}/columns('${name}')`);
119
+ const result = await this._graphAPI.doFetch(`${this.uri}/columns('${name}')`);
113
120
  return result.values;
114
121
  }
115
122
 
@@ -120,14 +127,14 @@ export class Table {
120
127
  if (index !== undefined) {
121
128
  body.index = index;
122
129
  }
123
- return this._oneDrive.doFetch(`${this.uri}/columns`, false, {
130
+ return this._graphAPI.doFetch(`${this.uri}/columns`, false, {
124
131
  method: 'POST',
125
132
  body,
126
133
  });
127
134
  }
128
135
 
129
136
  async deleteColumn(name) {
130
- return this._oneDrive.doFetch(`${this.uri}/columns/${name}`, true, {
137
+ return this._graphAPI.doFetch(`${this.uri}/columns/${name}`, true, {
131
138
  method: 'DELETE',
132
139
  });
133
140
  }
@@ -145,6 +152,34 @@ export class Table {
145
152
  }
146
153
 
147
154
  range() {
148
- return new Range(this._oneDrive, `${this.uri}/range`, this._log);
155
+ return new Range(this._graphAPI, `${this.uri}/range`, this._log);
156
+ }
157
+
158
+ async clearFilters() {
159
+ await this._graphAPI.doFetch(`${this.uri}/clearFilters`, true, {
160
+ method: 'POST',
161
+ });
162
+ }
163
+
164
+ async applyFilter(column, criteria) {
165
+ await this._graphAPI.doFetch(`${this.uri}/columns/${column}/filter/apply`, true, {
166
+ method: 'POST',
167
+ body: JSON.stringify({ criteria }),
168
+ });
169
+ }
170
+
171
+ async getVisibleRowsAsObjectsWithAddresses(maxRows = -1) {
172
+ // +1 to maxRows since result is inclusive of header
173
+ const pathSuffix = maxRows !== -1 ? `?$top=${maxRows + 1}` : '';
174
+ const path = `${this.uri}/range/visibleView/rows${pathSuffix}`;
175
+ const resp = await this._graphAPI.doFetch(path);
176
+ const headers = resp.value.shift().values[0];
177
+ return resp.value.map((row) => ({
178
+ cellAddresses: row.cellAddresses[0],
179
+ data: headers.reduce(
180
+ (rowObj, colName, colIdx, _) => ({ ...rowObj, [colName]: row.values[0][colIdx] }),
181
+ {},
182
+ ),
183
+ }));
149
184
  }
150
185
  }
@@ -15,21 +15,29 @@ import { Table } from './Table.js';
15
15
  import { Worksheet } from './Worksheet.js';
16
16
 
17
17
  export class Workbook extends NamedItemContainer {
18
- constructor(oneDrive, uri, log) {
19
- super(oneDrive);
20
-
21
- this._oneDrive = oneDrive;
18
+ /**
19
+ * Create a new instance of this class.
20
+ * @param {import('../GraphAPI.js').GraphAPI} graphAPI graph API
21
+ * @param {string} uri relative URI
22
+ * @param {any} log logger
23
+ */
24
+ constructor(graphAPI, uri, log) {
25
+ super(graphAPI);
26
+
27
+ this._graphAPI = graphAPI;
22
28
  this._uri = uri;
23
29
  this._log = log;
24
30
  }
25
31
 
26
- async createSession() {
32
+ async createSession(persistChanges = true) {
27
33
  if (this._sessionId) {
28
34
  throw new StatusCodeError('This workbook is already associated with a session', 400);
29
35
  }
30
36
  const uri = `${this.uri}/createSession`;
31
- const result = await this._oneDrive.doFetch(uri, false, {
37
+ const result = await this._graphAPI.doFetch(uri, false, {
32
38
  method: 'POST',
39
+ headers: { 'Content-Type': 'application/json' },
40
+ body: JSON.stringify({ persistChanges }),
33
41
  });
34
42
  this._sessionId = result.id;
35
43
  return this._sessionId;
@@ -38,7 +46,7 @@ export class Workbook extends NamedItemContainer {
38
46
  async closeSession() {
39
47
  if (this._sessionId) {
40
48
  const uri = `${this.uri}/closeSession`;
41
- await this._oneDrive.doFetch(uri, false, {
49
+ await this._graphAPI.doFetch(uri, false, {
42
50
  method: 'POST',
43
51
  headers: {
44
52
  'Workbook-Session-Id': this._sessionId,
@@ -53,7 +61,7 @@ export class Workbook extends NamedItemContainer {
53
61
  async refreshSession() {
54
62
  if (this._sessionId) {
55
63
  const uri = `${this.uri}/refreshSession`;
56
- await this._oneDrive.doFetch(uri, false, {
64
+ await this._graphAPI.doFetch(uri, false, {
57
65
  method: 'POST',
58
66
  headers: {
59
67
  'Workbook-Session-Id': this._sessionId,
@@ -83,7 +91,7 @@ export class Workbook extends NamedItemContainer {
83
91
  if (this._sessionId) {
84
92
  opts.headers['Workbook-Session-Id'] = this._sessionId;
85
93
  }
86
- return this._oneDrive.doFetch(relUrl, rawResponseBody, opts);
94
+ return this._graphAPI.doFetch(relUrl, rawResponseBody, opts);
87
95
  }
88
96
 
89
97
  async getData() {
@@ -15,10 +15,17 @@ import { Table } from './Table.js';
15
15
  import { Range } from './Range.js';
16
16
 
17
17
  export class Worksheet extends NamedItemContainer {
18
- constructor(oneDrive, prefix, name, log) {
19
- super(oneDrive);
18
+ /**
19
+ * Create a new instance of this class.
20
+ * @param {import('../GraphAPI.js').GraphAPI} graphAPI graph API
21
+ * @param {string} prefix URI prefix for this sheet
22
+ * @param {string} name sheet name
23
+ * @param {any} log logger
24
+ */
25
+ constructor(graphAPI, prefix, name, log) {
26
+ super(graphAPI);
20
27
 
21
- this._oneDrive = oneDrive;
28
+ this._graphAPI = graphAPI;
22
29
  this._uri = `${prefix}/${name}`;
23
30
  this._name = name;
24
31
  this._log = log;
@@ -33,18 +40,18 @@ export class Worksheet extends NamedItemContainer {
33
40
  }
34
41
 
35
42
  async getData() {
36
- const result = await this._oneDrive.doFetch(this._uri);
43
+ const result = await this._graphAPI.doFetch(this._uri);
37
44
  return result.value;
38
45
  }
39
46
 
40
47
  async getTableNames() {
41
48
  this.log.debug(`get table names from ${this._uri}/tables`);
42
- const result = await this._oneDrive.doFetch(`${this._uri}/tables`);
49
+ const result = await this._graphAPI.doFetch(`${this._uri}/tables`);
43
50
  return result.value.map((v) => v.name);
44
51
  }
45
52
 
46
53
  table(name) {
47
- return new Table(this._oneDrive, `${this._uri}/tables`, name, this._log);
54
+ return new Table(this._graphAPI, `${this._uri}/tables`, name, this._log);
48
55
  }
49
56
 
50
57
  async addTable(address, hasHeaders, name) {
@@ -54,7 +61,7 @@ export class Worksheet extends NamedItemContainer {
54
61
  throw new StatusCodeError(`Table name already exists: ${name}`, 409);
55
62
  }
56
63
  }
57
- const result = await this._oneDrive.doFetch(`${this.uri}/tables/add`, false, {
64
+ const result = await this._graphAPI.doFetch(`${this.uri}/tables/add`, false, {
58
65
  method: 'POST',
59
66
  body: {
60
67
  address,
@@ -69,10 +76,10 @@ export class Worksheet extends NamedItemContainer {
69
76
  }
70
77
 
71
78
  usedRange() {
72
- return new Range(this._oneDrive, `${this._uri}/usedRange`, this._log);
79
+ return new Range(this._graphAPI, `${this._uri}/usedRange`, this._log);
73
80
  }
74
81
 
75
82
  range(address) {
76
- return new Range(this._oneDrive, `${this._uri}/range(address='${address}')`, this._log);
83
+ return new Range(this._graphAPI, `${this._uri}/range(address='${address}')`, this._log);
77
84
  }
78
85
  }