@adobe/helix-onedrive-support 8.1.3 → 8.2.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [8.2.0](https://github.com/adobe/helix-onedrive-support/compare/v8.1.3...v8.2.0) (2022-07-29)
2
+
3
+
4
+ ### Features
5
+
6
+ * add table ([#288](https://github.com/adobe/helix-onedrive-support/issues/288)) ([fd02048](https://github.com/adobe/helix-onedrive-support/commit/fd020486af2d355cf31e61a190bcf522031a15c2))
7
+
1
8
  ## [8.1.3](https://github.com/adobe/helix-onedrive-support/compare/v8.1.2...v8.1.3) (2022-07-23)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-onedrive-support",
3
- "version": "8.1.3",
3
+ "version": "8.2.0",
4
4
  "description": "Helix OneDrive Support",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -10,8 +10,8 @@
10
10
  "type": "module",
11
11
  "types": "src/index.d.ts",
12
12
  "scripts": {
13
- "test": "c8 mocha",
14
- "test-ci": "c8 mocha && codecov",
13
+ "test": "c8 mocha --spec=test/**/*.test.js",
14
+ "test-ci": "c8 mocha --spec=test/**/*.test.js && codecov",
15
15
  "lint": "./node_modules/.bin/eslint .",
16
16
  "semantic-release": "semantic-release",
17
17
  "docs": "npx jsdoc2md -c .jsdoc.json --files 'src/*.js' > docs/API.md",
@@ -60,7 +60,6 @@
60
60
  "*.js": "eslint"
61
61
  },
62
62
  "mocha": {
63
- "spec": "test/**/*.test.js",
64
63
  "require": "test/setup-env.js",
65
64
  "reporter": "mocha-multi-reporters",
66
65
  "reporter-options": "configFile=.mocha-multi.json"
@@ -60,79 +60,84 @@ function handleNamedItems(sheet, segs, method, body) {
60
60
  * @returns {object} The response value
61
61
  */
62
62
  function handleTable(sheet, segs, method, body) {
63
+ const first = segs.shift();
64
+ if (!first) {
65
+ return { value: sheet.tables.map((table) => ({ name: table.name })) };
66
+ }
67
+ if (first === 'add') {
68
+ const len = sheet.tables.push({
69
+ name: `Table${sheet.tables.length + 1}`,
70
+ });
71
+ return sheet.tables[len - 1];
72
+ }
73
+ const table = sheet.tables.find((t) => t.name === first);
74
+ if (!table) {
75
+ throw new StatusCodeError(first, 404);
76
+ }
77
+ let command;
78
+ let name;
63
79
  if (segs[0]) {
64
- const tableName = segs.shift();
65
- const table = sheet.tables.find((t) => t.name === tableName);
66
- if (!table) {
67
- throw new StatusCodeError(tableName, 404);
68
- }
69
- let command;
70
- let name;
71
- if (segs[0]) {
72
- [, command, , name] = segs.shift().match(/([^?(]+)(\('([^)]+)'\))?(\?(.+))?/);
73
- }
74
- switch (command) {
75
- case 'dataBodyRange':
76
- return { rowCount: table.rows.length };
77
- case 'headerRowRange':
78
- return { values: [table.headerNames] };
79
- case 'rows': {
80
- if (!segs[0]) {
81
- return { value: table.rows.map((row) => ({ values: [row] })) };
82
- }
83
- const subCommand = segs.shift();
84
- if (subCommand === 'add') {
85
- table.rows.push(...body.values);
86
- return { index: table.rows.length - 1 };
87
- }
88
- const index = parseInt(subCommand.replace(/itemAt\(index=([0-9]+)\)/, '$1'), 10);
89
- if (index < 0 || index >= table.rows.length) {
90
- throw new StatusCodeError(`Index out of range: ${index}`, 400);
91
- }
92
- if (method === 'DELETE') {
93
- table.rows.splice(index, 1);
94
- return null;
95
- }
96
- if (body) {
97
- [table.rows[index]] = body.values;
98
- }
99
- return { values: [table.rows[index]] };
80
+ [, command, , name] = segs.shift().match(/([^?(]+)(\('([^)]+)'\))?(\?(.+))?/);
81
+ }
82
+ switch (command) {
83
+ case 'dataBodyRange':
84
+ return { rowCount: table.rows.length };
85
+ case 'headerRowRange':
86
+ return { values: [table.headerNames] };
87
+ case 'rows': {
88
+ if (!segs[0]) {
89
+ return { value: table.rows.map((row) => ({ values: [row] })) };
90
+ }
91
+ const subCommand = segs.shift();
92
+ if (subCommand === 'add') {
93
+ table.rows.push(...body.values);
94
+ return { index: table.rows.length - 1 };
95
+ }
96
+ const index = parseInt(subCommand.replace(/itemAt\(index=([0-9]+)\)/, '$1'), 10);
97
+ if (index < 0 || index >= table.rows.length) {
98
+ throw new StatusCodeError(`Index out of range: ${index}`, 400);
100
99
  }
101
- case 'columns': {
102
- if (!name) {
103
- const cols = table.headerNames.map((n) => ({
104
- name: n,
105
- values: [[n]],
106
- }));
107
- table.rows.forEach((row) => {
108
- row.forEach((value, idx) => {
109
- cols[idx].values.push([value]);
110
- });
100
+ if (method === 'DELETE') {
101
+ table.rows.splice(index, 1);
102
+ return null;
103
+ }
104
+ if (body) {
105
+ [table.rows[index]] = body.values;
106
+ }
107
+ return { values: [table.rows[index]] };
108
+ }
109
+ case 'columns': {
110
+ if (!name) {
111
+ const cols = table.headerNames.map((n) => ({
112
+ name: n,
113
+ values: [[n]],
114
+ }));
115
+ table.rows.forEach((row) => {
116
+ row.forEach((value, idx) => {
117
+ cols[idx].values.push([value]);
111
118
  });
112
- return {
113
- value: cols,
114
- };
115
- }
116
- const columnName = name;
117
- const index = table.headerNames.findIndex((n) => n === columnName);
118
- if (index === -1) {
119
- throw new StatusCodeError(`Column name not found: ${columnName}`, 400);
120
- }
119
+ });
121
120
  return {
122
- values: [
123
- [table.headerNames[index]],
124
- ...table.rows.map((row) => [row[index]]),
125
- ],
121
+ value: cols,
126
122
  };
127
123
  }
128
- default:
129
- if (body) {
130
- table.name = body.name;
131
- }
132
- return { values: table.name };
124
+ const columnName = name;
125
+ const index = table.headerNames.findIndex((n) => n === columnName);
126
+ if (index === -1) {
127
+ throw new StatusCodeError(`Column name not found: ${columnName}`, 400);
128
+ }
129
+ return {
130
+ values: [
131
+ [table.headerNames[index]],
132
+ ...table.rows.map((row) => [row[index]]),
133
+ ],
134
+ };
133
135
  }
134
- } else {
135
- return { value: sheet.tables.map((table) => ({ name: table.name })) };
136
+ default:
137
+ if (body) {
138
+ table.name = body.name;
139
+ }
140
+ return { values: table.name };
136
141
  }
137
142
  }
138
143
 
@@ -309,7 +314,8 @@ export class OneDriveMock extends OneDrive {
309
314
  }
310
315
 
311
316
  // handle the operations on the workbook / worksheet
312
- switch (segs.shift()) {
317
+ const type = segs.shift();
318
+ switch (type) {
313
319
  case 'usedRange':
314
320
  return sheet.usedRange;
315
321
  case 'tables':
@@ -317,6 +323,11 @@ export class OneDriveMock extends OneDrive {
317
323
  case 'names':
318
324
  return handleNamedItems(sheet, segs, method, body);
319
325
  default:
326
+ if (type && type.startsWith('range(address=')) {
327
+ return {
328
+ address: type.match(/range\(address='([^)]+)'\)/)[1],
329
+ };
330
+ }
320
331
  // default return the data
321
332
  return { value: data };
322
333
  }
@@ -125,6 +125,10 @@ export class Table {
125
125
  });
126
126
  }
127
127
 
128
+ get name() {
129
+ return this._name;
130
+ }
131
+
128
132
  get uri() {
129
133
  return `${this._prefix}/${this._name}`;
130
134
  }
@@ -42,6 +42,17 @@ export declare interface Workbook {
42
42
  */
43
43
  table(name: string): Table;
44
44
 
45
+ /**
46
+ * Add a table to a workbook. If a name is passed that is not
47
+ * identical to one automatically given, the table gets
48
+ * automatically renamed.
49
+ *
50
+ * @param address address of table, e.g. Sheet1!A1:C1
51
+ * @param hasHeaders whether the table has headers
52
+ * @param name optional name
53
+ */
54
+ addTable(address: string, hasHeaders: boolean, name?: string): Promise<Table>;
55
+
45
56
  /**
46
57
  * Return the named items in a work book
47
58
  * @returns array of named items when resolved
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
  import { NamedItemContainer } from './NamedItemContainer.js';
13
+ import { StatusCodeError } from '../StatusCodeError.js';
13
14
  import { Table } from './Table.js';
14
15
  import { Worksheet } from './Worksheet.js';
15
16
 
@@ -47,6 +48,27 @@ export class Workbook extends NamedItemContainer {
47
48
  return new Table(this._oneDrive, `${this._uri}/tables`, name, this._log);
48
49
  }
49
50
 
51
+ async addTable(address, hasHeaders, name) {
52
+ if (name) {
53
+ const names = await this.getTableNames();
54
+ if (names.includes(name)) {
55
+ throw new StatusCodeError(`Table name already exists: ${name}`, 409);
56
+ }
57
+ }
58
+ const result = await this._oneDrive.doFetch(`${this.uri}/tables/add`, false, {
59
+ method: 'POST',
60
+ body: {
61
+ address,
62
+ hasHeaders,
63
+ },
64
+ });
65
+ const table = this.table(result.name);
66
+ if (name && name !== table.name) {
67
+ await table.rename(name);
68
+ }
69
+ return table;
70
+ }
71
+
50
72
  get uri() {
51
73
  return this._uri;
52
74
  }
@@ -57,6 +57,17 @@ export declare interface Worksheet {
57
57
  */
58
58
  table(name: string): Table;
59
59
 
60
+ /**
61
+ * Add a table to a workbook. If a name is passed that is not
62
+ * identical to one automatically given, the table gets
63
+ * automatically renamed.
64
+ *
65
+ * @param address address of table in sheet, e.g. A1:C1
66
+ * @param hasHeaders whether the table has headers
67
+ * @param name optional name
68
+ */
69
+ addTable(address: string, hasHeaders: boolean, name?: string): Promise<Table>;
70
+
60
71
  /**
61
72
  * Returns the use name.
62
73
  */
@@ -10,6 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
  import { NamedItemContainer } from './NamedItemContainer.js';
13
+ import { StatusCodeError } from '../StatusCodeError.js';
13
14
  import { Table } from './Table.js';
14
15
  import { Range } from './Range.js';
15
16
 
@@ -46,6 +47,27 @@ export class Worksheet extends NamedItemContainer {
46
47
  return new Table(this._oneDrive, `${this._uri}/tables`, name, this._log);
47
48
  }
48
49
 
50
+ async addTable(address, hasHeaders, name) {
51
+ if (name) {
52
+ const names = await this.getTableNames();
53
+ if (names.includes(name)) {
54
+ throw new StatusCodeError(`Table name already exists: ${name}`, 409);
55
+ }
56
+ }
57
+ const result = await this._oneDrive.doFetch(`${this.uri}/tables/add`, false, {
58
+ method: 'POST',
59
+ body: {
60
+ address,
61
+ hasHeaders,
62
+ },
63
+ });
64
+ const table = this.table(result.name);
65
+ if (name && name !== table.name) {
66
+ await table.rename(name);
67
+ }
68
+ return table;
69
+ }
70
+
49
71
  usedRange() {
50
72
  return new Range(this._oneDrive, `${this._uri}/usedRange`, this._log);
51
73
  }