@cj-tech-master/excelts 1.4.3 → 1.4.5-canary.20251212053535.13d32d8

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.
Files changed (80) hide show
  1. package/README.md +3 -3
  2. package/README_zh.md +3 -3
  3. package/dist/browser/excelts.iife.js +13026 -7610
  4. package/dist/browser/excelts.iife.js.map +1 -1
  5. package/dist/browser/excelts.iife.min.js +87 -24
  6. package/dist/cjs/doc/anchor.js +25 -11
  7. package/dist/cjs/doc/cell.js +75 -43
  8. package/dist/cjs/doc/column.js +39 -16
  9. package/dist/cjs/doc/defined-names.js +53 -7
  10. package/dist/cjs/doc/image.js +11 -8
  11. package/dist/cjs/doc/range.js +64 -28
  12. package/dist/cjs/doc/row.js +33 -17
  13. package/dist/cjs/doc/table.js +3 -5
  14. package/dist/cjs/doc/workbook.js +5 -4
  15. package/dist/cjs/doc/worksheet.js +24 -20
  16. package/dist/cjs/stream/xlsx/workbook-writer.js +3 -2
  17. package/dist/cjs/utils/sheet-utils.js +3 -1
  18. package/dist/cjs/utils/unzip/extract.js +166 -0
  19. package/dist/cjs/utils/unzip/index.js +7 -1
  20. package/dist/cjs/utils/xml-stream.js +25 -3
  21. package/dist/cjs/utils/zip/compress.js +261 -0
  22. package/dist/cjs/utils/zip/crc32.js +154 -0
  23. package/dist/cjs/utils/zip/index.js +70 -0
  24. package/dist/cjs/utils/zip/zip-builder.js +378 -0
  25. package/dist/cjs/utils/zip-stream.js +30 -34
  26. package/dist/cjs/xlsx/xform/book/defined-name-xform.js +36 -2
  27. package/dist/cjs/xlsx/xform/list-xform.js +6 -0
  28. package/dist/cjs/xlsx/xform/sheet/cell-xform.js +6 -1
  29. package/dist/cjs/xlsx/xform/sheet/row-xform.js +24 -2
  30. package/dist/cjs/xlsx/xform/table/filter-column-xform.js +4 -0
  31. package/dist/esm/doc/anchor.js +25 -11
  32. package/dist/esm/doc/cell.js +75 -43
  33. package/dist/esm/doc/column.js +39 -16
  34. package/dist/esm/doc/defined-names.js +53 -7
  35. package/dist/esm/doc/image.js +11 -8
  36. package/dist/esm/doc/range.js +64 -28
  37. package/dist/esm/doc/row.js +33 -17
  38. package/dist/esm/doc/table.js +3 -5
  39. package/dist/esm/doc/workbook.js +5 -4
  40. package/dist/esm/doc/worksheet.js +24 -20
  41. package/dist/esm/stream/xlsx/workbook-writer.js +3 -2
  42. package/dist/esm/utils/sheet-utils.js +3 -1
  43. package/dist/esm/utils/unzip/extract.js +160 -0
  44. package/dist/esm/utils/unzip/index.js +2 -0
  45. package/dist/esm/utils/xml-stream.js +25 -3
  46. package/dist/esm/utils/zip/compress.js +220 -0
  47. package/dist/esm/utils/zip/crc32.js +116 -0
  48. package/dist/esm/utils/zip/index.js +55 -0
  49. package/dist/esm/utils/zip/zip-builder.js +372 -0
  50. package/dist/esm/utils/zip-stream.js +30 -34
  51. package/dist/esm/xlsx/xform/book/defined-name-xform.js +36 -2
  52. package/dist/esm/xlsx/xform/list-xform.js +6 -0
  53. package/dist/esm/xlsx/xform/sheet/cell-xform.js +6 -1
  54. package/dist/esm/xlsx/xform/sheet/row-xform.js +24 -2
  55. package/dist/esm/xlsx/xform/table/filter-column-xform.js +4 -0
  56. package/dist/types/doc/anchor.d.ts +14 -7
  57. package/dist/types/doc/cell.d.ts +85 -40
  58. package/dist/types/doc/column.d.ts +39 -34
  59. package/dist/types/doc/defined-names.d.ts +11 -8
  60. package/dist/types/doc/image.d.ts +29 -12
  61. package/dist/types/doc/pivot-table.d.ts +1 -1
  62. package/dist/types/doc/range.d.ts +15 -4
  63. package/dist/types/doc/row.d.ts +34 -40
  64. package/dist/types/doc/table.d.ts +21 -36
  65. package/dist/types/doc/workbook.d.ts +30 -33
  66. package/dist/types/doc/worksheet.d.ts +105 -80
  67. package/dist/types/stream/xlsx/worksheet-reader.d.ts +3 -5
  68. package/dist/types/types.d.ts +86 -26
  69. package/dist/types/utils/col-cache.d.ts +11 -8
  70. package/dist/types/utils/unzip/extract.d.ts +92 -0
  71. package/dist/types/utils/unzip/index.d.ts +1 -0
  72. package/dist/types/utils/xml-stream.d.ts +2 -0
  73. package/dist/types/utils/zip/compress.d.ts +83 -0
  74. package/dist/types/utils/zip/crc32.d.ts +55 -0
  75. package/dist/types/utils/zip/index.d.ts +52 -0
  76. package/dist/types/utils/zip/zip-builder.d.ts +110 -0
  77. package/dist/types/utils/zip-stream.d.ts +6 -12
  78. package/dist/types/xlsx/xform/list-xform.d.ts +1 -0
  79. package/dist/types/xlsx/xform/sheet/row-xform.d.ts +2 -0
  80. package/package.json +8 -8
@@ -1,4 +1,14 @@
1
1
  import { colCache } from "../utils/col-cache.js";
2
+ function isAnchorModel(value) {
3
+ return (typeof value === "object" &&
4
+ "nativeCol" in value &&
5
+ "nativeRow" in value &&
6
+ "nativeColOff" in value &&
7
+ "nativeRowOff" in value);
8
+ }
9
+ function isSimpleAddress(value) {
10
+ return typeof value === "object" && "col" in value && "row" in value;
11
+ }
2
12
  class Anchor {
3
13
  constructor(worksheet, address, offset = 0) {
4
14
  this.worksheet = worksheet;
@@ -15,17 +25,15 @@ class Anchor {
15
25
  this.nativeRow = decoded.row + offset;
16
26
  this.nativeRowOff = 0;
17
27
  }
18
- else if (address.nativeCol !== undefined) {
19
- const anchor = address;
20
- this.nativeCol = anchor.nativeCol || 0;
21
- this.nativeColOff = anchor.nativeColOff || 0;
22
- this.nativeRow = anchor.nativeRow || 0;
23
- this.nativeRowOff = anchor.nativeRowOff || 0;
28
+ else if (isAnchorModel(address)) {
29
+ this.nativeCol = address.nativeCol || 0;
30
+ this.nativeColOff = address.nativeColOff || 0;
31
+ this.nativeRow = address.nativeRow || 0;
32
+ this.nativeRowOff = address.nativeRowOff || 0;
24
33
  }
25
- else if (address.col !== undefined) {
26
- const simple = address;
27
- this.col = simple.col + offset;
28
- this.row = simple.row + offset;
34
+ else if (isSimpleAddress(address)) {
35
+ this.col = address.col + offset;
36
+ this.row = address.row + offset;
29
37
  }
30
38
  else {
31
39
  this.nativeCol = 0;
@@ -35,7 +43,13 @@ class Anchor {
35
43
  }
36
44
  }
37
45
  static asInstance(model) {
38
- return model instanceof Anchor || model == null ? model : new Anchor(undefined, model);
46
+ if (model == null) {
47
+ return null;
48
+ }
49
+ if (model instanceof Anchor) {
50
+ return model;
51
+ }
52
+ return new Anchor(undefined, model);
39
53
  }
40
54
  get col() {
41
55
  return this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;
@@ -184,11 +184,30 @@ class Cell {
184
184
  this._value = Value.create(Value.getType(v), this, v);
185
185
  }
186
186
  get note() {
187
- return this._comment && this._comment.note;
187
+ if (!this._comment) {
188
+ return undefined;
189
+ }
190
+ const noteValue = this._comment.note;
191
+ return noteValue;
188
192
  }
189
193
  set note(note) {
190
194
  this._comment = new Note(note);
191
195
  }
196
+ // Internal comment accessor for row operations
197
+ get comment() {
198
+ return this._comment;
199
+ }
200
+ set comment(comment) {
201
+ if (comment === undefined) {
202
+ this._comment = undefined;
203
+ }
204
+ else if (comment instanceof Note) {
205
+ this._comment = comment;
206
+ }
207
+ else {
208
+ this._comment = new Note(comment);
209
+ }
210
+ }
192
211
  get text() {
193
212
  return this._value.toString();
194
213
  }
@@ -202,7 +221,7 @@ class Cell {
202
221
  // if this cell is a string, turn it into a Hyperlink
203
222
  if (this.type === Cell.Types.String) {
204
223
  this._value = Value.create(Cell.Types.Hyperlink, this, {
205
- text: this._value.value,
224
+ text: String(this._value.value),
206
225
  hyperlink
207
226
  });
208
227
  }
@@ -295,8 +314,6 @@ class Cell {
295
314
  }
296
315
  }
297
316
  Cell.Types = Enums.ValueType;
298
- // =============================================================================
299
- // Internal Value Types
300
317
  class NullValue {
301
318
  constructor(cell) {
302
319
  this.model = {
@@ -413,7 +430,7 @@ class RichTextValue {
413
430
  this.model.value = value;
414
431
  }
415
432
  toString() {
416
- return this.model.value.richText.map((t) => t.text).join("");
433
+ return this.model.value.richText.map(t => t.text).join("");
417
434
  }
418
435
  get type() {
419
436
  return Cell.Types.RichText;
@@ -482,14 +499,11 @@ class HyperlinkValue {
482
499
  }
483
500
  }
484
501
  get value() {
485
- const v = {
486
- text: this.model.text,
487
- hyperlink: this.model.hyperlink
502
+ return {
503
+ text: this.model.text || "",
504
+ hyperlink: this.model.hyperlink || "",
505
+ tooltip: this.model.tooltip
488
506
  };
489
- if (this.model.tooltip) {
490
- v.tooltip = this.model.tooltip;
491
- }
492
- return v;
493
507
  }
494
508
  set value(value) {
495
509
  this.model.text = value.text;
@@ -600,24 +614,42 @@ class FormulaValue {
600
614
  }
601
615
  _copyModel(model) {
602
616
  const copy = {};
603
- const cp = (name) => {
604
- const value = model[name];
605
- if (value) {
606
- copy[name] = value;
607
- }
608
- };
609
- cp("formula");
610
- cp("result");
611
- cp("ref");
612
- cp("shareType");
613
- cp("sharedFormula");
617
+ if (model.formula) {
618
+ copy.formula = model.formula;
619
+ }
620
+ if (model.result !== undefined) {
621
+ copy.result = model.result;
622
+ }
623
+ if (model.ref) {
624
+ copy.ref = model.ref;
625
+ }
626
+ if (model.shareType) {
627
+ copy.shareType = model.shareType;
628
+ }
629
+ if (model.sharedFormula) {
630
+ copy.sharedFormula = model.sharedFormula;
631
+ }
614
632
  return copy;
615
633
  }
616
634
  get value() {
617
635
  return this._copyModel(this.model);
618
636
  }
619
637
  set value(value) {
620
- this.model = this._copyModel(value);
638
+ if (value.formula) {
639
+ this.model.formula = value.formula;
640
+ }
641
+ if (value.result !== undefined) {
642
+ this.model.result = value.result;
643
+ }
644
+ if (value.ref) {
645
+ this.model.ref = value.ref;
646
+ }
647
+ if (value.shareType) {
648
+ this.model.shareType = value.shareType;
649
+ }
650
+ if (value.sharedFormula) {
651
+ this.model.sharedFormula = value.sharedFormula;
652
+ }
621
653
  }
622
654
  validate(value) {
623
655
  switch (Value.getType(value)) {
@@ -681,11 +713,8 @@ class FormulaValue {
681
713
  if (v instanceof Date) {
682
714
  return Enums.ValueType.Date;
683
715
  }
684
- if (v.text && v.hyperlink) {
685
- return Enums.ValueType.Hyperlink;
686
- }
687
- if (v.formula) {
688
- return Enums.ValueType.Formula;
716
+ if (typeof v === "object" && "error" in v) {
717
+ return Enums.ValueType.Error;
689
718
  }
690
719
  return Enums.ValueType.Null;
691
720
  }
@@ -868,20 +897,23 @@ const Value = {
868
897
  if (value instanceof Date) {
869
898
  return Cell.Types.Date;
870
899
  }
871
- if (value.text && value.hyperlink) {
872
- return Cell.Types.Hyperlink;
873
- }
874
- if (value.formula || value.sharedFormula) {
875
- return Cell.Types.Formula;
876
- }
877
- if (value.richText) {
878
- return Cell.Types.RichText;
879
- }
880
- if (value.sharedString) {
881
- return Cell.Types.SharedString;
882
- }
883
- if (value.error) {
884
- return Cell.Types.Error;
900
+ if (typeof value === "object") {
901
+ if ("text" in value && value.text && "hyperlink" in value && value.hyperlink) {
902
+ return Cell.Types.Hyperlink;
903
+ }
904
+ if (("formula" in value && value.formula) ||
905
+ ("sharedFormula" in value && value.sharedFormula)) {
906
+ return Cell.Types.Formula;
907
+ }
908
+ if ("richText" in value && value.richText) {
909
+ return Cell.Types.RichText;
910
+ }
911
+ if ("sharedString" in value && value.sharedString) {
912
+ return Cell.Types.SharedString;
913
+ }
914
+ if ("error" in value && value.error) {
915
+ return Cell.Types.Error;
916
+ }
885
917
  }
886
918
  return Cell.Types.JSON;
887
919
  },
@@ -60,7 +60,13 @@ class Column {
60
60
  }
61
61
  }
62
62
  get headers() {
63
- return this._header && this._header instanceof Array ? this._header : [this._header];
63
+ if (Array.isArray(this._header)) {
64
+ return this._header;
65
+ }
66
+ if (this._header !== undefined) {
67
+ return [this._header];
68
+ }
69
+ return [];
64
70
  }
65
71
  get header() {
66
72
  return this._header;
@@ -117,6 +123,12 @@ class Column {
117
123
  this.outlineLevel === other.outlineLevel &&
118
124
  isEqual(this.style, other.style));
119
125
  }
126
+ equivalentToModel(model) {
127
+ return (this.width === model.width &&
128
+ this.hidden === model.hidden &&
129
+ this.outlineLevel === model.outlineLevel &&
130
+ isEqual(this.style, model.style));
131
+ }
120
132
  get isDefault() {
121
133
  if (this.isCustomWidth) {
122
134
  return false;
@@ -140,7 +152,7 @@ class Column {
140
152
  const colNumber = this.number;
141
153
  if (!iteratee) {
142
154
  iteratee = options;
143
- options = null;
155
+ options = {};
144
156
  }
145
157
  this._worksheet.eachRow(options, (row, rowNumber) => {
146
158
  iteratee(row.getCell(colNumber), rowNumber);
@@ -171,48 +183,59 @@ class Column {
171
183
  }
172
184
  // =========================================================================
173
185
  // styles
174
- _applyStyle(name, value) {
175
- this.style[name] = value;
176
- this.eachCell((cell) => {
177
- cell[name] = value;
178
- });
179
- return value;
180
- }
181
186
  get numFmt() {
182
187
  return this.style.numFmt;
183
188
  }
184
189
  set numFmt(value) {
185
- this._applyStyle("numFmt", value);
190
+ this.style.numFmt = value;
191
+ this.eachCell(cell => {
192
+ cell.numFmt = value;
193
+ });
186
194
  }
187
195
  get font() {
188
196
  return this.style.font;
189
197
  }
190
198
  set font(value) {
191
- this._applyStyle("font", value);
199
+ this.style.font = value;
200
+ this.eachCell(cell => {
201
+ cell.font = value;
202
+ });
192
203
  }
193
204
  get alignment() {
194
205
  return this.style.alignment;
195
206
  }
196
207
  set alignment(value) {
197
- this._applyStyle("alignment", value);
208
+ this.style.alignment = value;
209
+ this.eachCell(cell => {
210
+ cell.alignment = value;
211
+ });
198
212
  }
199
213
  get protection() {
200
214
  return this.style.protection;
201
215
  }
202
216
  set protection(value) {
203
- this._applyStyle("protection", value);
217
+ this.style.protection = value;
218
+ this.eachCell(cell => {
219
+ cell.protection = value;
220
+ });
204
221
  }
205
222
  get border() {
206
223
  return this.style.border;
207
224
  }
208
225
  set border(value) {
209
- this._applyStyle("border", value);
226
+ this.style.border = value;
227
+ this.eachCell(cell => {
228
+ cell.border = value;
229
+ });
210
230
  }
211
231
  get fill() {
212
232
  return this.style.fill;
213
233
  }
214
234
  set fill(value) {
215
- this._applyStyle("fill", value);
235
+ this.style.fill = value;
236
+ this.eachCell(cell => {
237
+ cell.fill = value;
238
+ });
216
239
  }
217
240
  // =============================================================================
218
241
  // static functions
@@ -227,7 +250,7 @@ class Column {
227
250
  col = null;
228
251
  }
229
252
  }
230
- else if (!col || !column.equivalentTo(col)) {
253
+ else if (!col || !column.equivalentToModel(col)) {
231
254
  col = {
232
255
  min: index + 1,
233
256
  max: index + 1,
@@ -13,11 +13,15 @@ class DefinedNames {
13
13
  // add a name to a cell. locStr in the form SheetName!$col$row or SheetName!$c1$r1:$c2:$r2
14
14
  add(locStr, name) {
15
15
  const location = colCache.decodeEx(locStr);
16
+ if ("error" in location) {
17
+ return; // Invalid reference, skip
18
+ }
16
19
  this.addEx(location, name);
17
20
  }
18
21
  addEx(location, name) {
19
22
  const matrix = this.getMatrix(name);
20
- if (location.top) {
23
+ if ("top" in location) {
24
+ // It's a range (DecodedRange has top/left/bottom/right from Location)
21
25
  for (let col = location.left; col <= location.right; col++) {
22
26
  for (let row = location.top; row <= location.bottom; row++) {
23
27
  const address = {
@@ -31,20 +35,54 @@ class DefinedNames {
31
35
  }
32
36
  }
33
37
  else {
38
+ // It's a single cell address
34
39
  matrix.addCellEx(location);
35
40
  }
36
41
  }
37
42
  remove(locStr, name) {
38
43
  const location = colCache.decodeEx(locStr);
44
+ if ("error" in location) {
45
+ return; // Invalid reference, skip
46
+ }
39
47
  this.removeEx(location, name);
40
48
  }
41
49
  removeEx(location, name) {
42
50
  const matrix = this.getMatrix(name);
43
- matrix.removeCellEx(location);
51
+ if ("top" in location) {
52
+ // Range - remove each cell
53
+ for (let col = location.left; col <= location.right; col++) {
54
+ for (let row = location.top; row <= location.bottom; row++) {
55
+ matrix.removeCellEx({
56
+ sheetName: location.sheetName,
57
+ address: colCache.n2l(col) + row,
58
+ row,
59
+ col
60
+ });
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ matrix.removeCellEx(location);
66
+ }
44
67
  }
45
68
  removeAllNames(location) {
46
69
  Object.values(this.matrixMap).forEach((matrix) => {
47
- matrix.removeCellEx(location);
70
+ if ("top" in location) {
71
+ // Range - remove each cell
72
+ for (let col = location.left; col <= location.right; col++) {
73
+ for (let row = location.top; row <= location.bottom; row++) {
74
+ matrix.removeCellEx({
75
+ sheetName: location.sheetName,
76
+ address: colCache.n2l(col) + row,
77
+ row,
78
+ col
79
+ });
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ matrix.removeCellEx(location);
85
+ }
48
86
  });
49
87
  }
50
88
  forEach(callback) {
@@ -56,12 +94,16 @@ class DefinedNames {
56
94
  }
57
95
  // get all the names of a cell
58
96
  getNames(addressStr) {
59
- return this.getNamesEx(colCache.decodeEx(addressStr));
97
+ const location = colCache.decodeEx(addressStr);
98
+ if ("error" in location || "top" in location) {
99
+ return []; // Invalid reference or range not supported
100
+ }
101
+ return this.getNamesEx(location);
60
102
  }
61
103
  getNamesEx(address) {
62
104
  return Object.entries(this.matrixMap)
63
105
  .map(([name, matrix]) => matrix.findCellEx(address, false) && name)
64
- .filter(Boolean);
106
+ .filter((name) => Boolean(name));
65
107
  }
66
108
  _explore(matrix, cell) {
67
109
  cell.mark = false;
@@ -69,9 +111,13 @@ class DefinedNames {
69
111
  const range = new Range(cell.row, cell.col, cell.row, cell.col, sheetName);
70
112
  let x;
71
113
  let y;
114
+ // Helper to get cell with proper type
115
+ const getCell = (row, col) => {
116
+ return matrix.findCellAt(sheetName, row, col);
117
+ };
72
118
  // grow vertical - only one col to worry about
73
119
  function vGrow(yy, edge) {
74
- const c = matrix.findCellAt(sheetName, yy, cell.col);
120
+ const c = getCell(yy, cell.col);
75
121
  if (!c || !c.mark) {
76
122
  return false;
77
123
  }
@@ -85,7 +131,7 @@ class DefinedNames {
85
131
  function hGrow(xx, edge) {
86
132
  const cells = [];
87
133
  for (y = range.top; y <= range.bottom; y++) {
88
- const c = matrix.findCellAt(sheetName, y, xx);
134
+ const c = getCell(y, xx);
89
135
  if (c && c.mark) {
90
136
  cells.push(c);
91
137
  }
@@ -36,19 +36,22 @@ class Image {
36
36
  if (type === "image") {
37
37
  if (typeof range === "string") {
38
38
  const decoded = colCache.decode(range);
39
- this.range = {
40
- tl: new Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
41
- br: new Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
42
- editAs: "oneCell"
43
- };
39
+ if ("top" in decoded) {
40
+ // It's a Location (range like "A1:C3")
41
+ this.range = {
42
+ tl: new Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
43
+ br: new Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
44
+ editAs: "oneCell"
45
+ };
46
+ }
44
47
  }
45
- else {
48
+ else if (range) {
46
49
  this.range = {
47
50
  tl: new Anchor(this.worksheet, range.tl, 0),
48
- br: range.br && new Anchor(this.worksheet, range.br, 0),
51
+ br: range.br ? new Anchor(this.worksheet, range.br, 0) : undefined,
49
52
  ext: range.ext,
50
53
  editAs: range.editAs,
51
- hyperlinks: hyperlinks || range.hyperlinks
54
+ hyperlinks: hyperlinks || ("hyperlinks" in range ? range.hyperlinks : undefined)
52
55
  };
53
56
  }
54
57
  }
@@ -2,11 +2,17 @@ import { colCache } from "../utils/col-cache.js";
2
2
  // used by worksheet to calculate sheet dimensions
3
3
  class Range {
4
4
  constructor(...args) {
5
+ this.model = {
6
+ top: 0,
7
+ left: 0,
8
+ bottom: 0,
9
+ right: 0
10
+ };
5
11
  this.decode(args);
6
12
  }
7
13
  setTLBR(t, l, b, r, s) {
8
- if (arguments.length < 4) {
9
- // setTLBR(tl, br, s)
14
+ if (typeof t === "string" && typeof l === "string") {
15
+ // setTLBR(tl, br, s) - t and l are address strings
10
16
  const tl = colCache.decodeAddress(t);
11
17
  const br = colCache.decodeAddress(l);
12
18
  this.model = {
@@ -14,12 +20,14 @@ class Range {
14
20
  left: Math.min(tl.col, br.col),
15
21
  bottom: Math.max(tl.row, br.row),
16
22
  right: Math.max(tl.col, br.col),
17
- sheetName: b
23
+ sheetName: typeof b === "string" ? b : undefined
18
24
  };
19
- this.setTLBR(tl.row, tl.col, br.row, br.col, s);
20
25
  }
21
- else {
22
- // setTLBR(t, l, b, r, s)
26
+ else if (typeof t === "number" &&
27
+ typeof l === "number" &&
28
+ typeof b === "number" &&
29
+ typeof r === "number") {
30
+ // setTLBR(t, l, b, r, s) - all numbers
23
31
  this.model = {
24
32
  top: Math.min(t, b),
25
33
  left: Math.min(l, r),
@@ -32,16 +40,33 @@ class Range {
32
40
  decode(argv) {
33
41
  switch (argv.length) {
34
42
  case 5: // [t,l,b,r,s]
35
- this.setTLBR(argv[0], argv[1], argv[2], argv[3], argv[4]);
43
+ if (typeof argv[0] === "number" &&
44
+ typeof argv[1] === "number" &&
45
+ typeof argv[2] === "number" &&
46
+ typeof argv[3] === "number" &&
47
+ typeof argv[4] === "string") {
48
+ this.setTLBR(argv[0], argv[1], argv[2], argv[3], argv[4]);
49
+ }
36
50
  break;
37
51
  case 4: // [t,l,b,r]
38
- this.setTLBR(argv[0], argv[1], argv[2], argv[3]);
52
+ if (typeof argv[0] === "number" &&
53
+ typeof argv[1] === "number" &&
54
+ typeof argv[2] === "number" &&
55
+ typeof argv[3] === "number") {
56
+ this.setTLBR(argv[0], argv[1], argv[2], argv[3]);
57
+ }
39
58
  break;
40
59
  case 3: // [tl,br,s]
41
- this.setTLBR(argv[0], argv[1], argv[2]);
60
+ if (typeof argv[0] === "string" &&
61
+ typeof argv[1] === "string" &&
62
+ typeof argv[2] === "string") {
63
+ this.setTLBR(argv[0], argv[1], argv[2]);
64
+ }
42
65
  break;
43
66
  case 2: // [tl,br]
44
- this.setTLBR(argv[0], argv[1]);
67
+ if (typeof argv[0] === "string" && typeof argv[1] === "string") {
68
+ this.setTLBR(argv[0], argv[1]);
69
+ }
45
70
  break;
46
71
  case 1: {
47
72
  const value = argv[0];
@@ -55,11 +80,15 @@ class Range {
55
80
  sheetName: value.sheetName
56
81
  };
57
82
  }
58
- else if (value instanceof Array) {
83
+ else if (Array.isArray(value)) {
59
84
  // an arguments array
60
85
  this.decode(value);
61
86
  }
62
- else if (value.top && value.left && value.bottom && value.right) {
87
+ else if (typeof value === "object" &&
88
+ "top" in value &&
89
+ "left" in value &&
90
+ "bottom" in value &&
91
+ "right" in value) {
63
92
  // a model
64
93
  this.model = {
65
94
  top: value.top,
@@ -69,25 +98,27 @@ class Range {
69
98
  sheetName: value.sheetName
70
99
  };
71
100
  }
72
- else {
101
+ else if (typeof value === "string") {
73
102
  // [sheetName!]tl:br
74
- const tlbr = colCache.decodeEx(value);
75
- if (tlbr.top) {
103
+ const decoded = colCache.decodeEx(value);
104
+ if ("top" in decoded) {
105
+ // It's a DecodedRange
76
106
  this.model = {
77
- top: tlbr.top,
78
- left: tlbr.left,
79
- bottom: tlbr.bottom,
80
- right: tlbr.right,
81
- sheetName: tlbr.sheetName
107
+ top: decoded.top,
108
+ left: decoded.left,
109
+ bottom: decoded.bottom,
110
+ right: decoded.right,
111
+ sheetName: decoded.sheetName
82
112
  };
83
113
  }
84
- else {
114
+ else if ("row" in decoded) {
115
+ // It's an Address
85
116
  this.model = {
86
- top: tlbr.row,
87
- left: tlbr.col,
88
- bottom: tlbr.row,
89
- right: tlbr.col,
90
- sheetName: tlbr.sheetName
117
+ top: decoded.row,
118
+ left: decoded.col,
119
+ bottom: decoded.row,
120
+ right: decoded.col,
121
+ sheetName: decoded.sheetName
91
122
  };
92
123
  }
93
124
  }
@@ -169,7 +200,9 @@ class Range {
169
200
  }
170
201
  expandToAddress(addressStr) {
171
202
  const address = colCache.decodeEx(addressStr);
172
- this.expand(address.row, address.col, address.row, address.col);
203
+ if ("row" in address && "col" in address) {
204
+ this.expand(address.row, address.col, address.row, address.col);
205
+ }
173
206
  }
174
207
  get tl() {
175
208
  return colCache.n2l(this.left) + this.top;
@@ -221,7 +254,10 @@ class Range {
221
254
  }
222
255
  contains(addressStr) {
223
256
  const address = colCache.decodeEx(addressStr);
224
- return this.containsEx(address);
257
+ if ("row" in address && "col" in address) {
258
+ return this.containsEx(address);
259
+ }
260
+ return false;
225
261
  }
226
262
  containsEx(address) {
227
263
  if (address.sheetName && this.sheetName && address.sheetName !== this.sheetName) {