@cj-tech-master/excelts 1.4.0 → 1.4.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.
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DataValidations = void 0;
4
+ const col_cache_js_1 = require("../utils/col-cache");
4
5
  class DataValidations {
5
6
  constructor(model) {
6
7
  this.model = model || {};
@@ -9,7 +10,34 @@ class DataValidations {
9
10
  return (this.model[address] = validation);
10
11
  }
11
12
  find(address) {
12
- return this.model[address];
13
+ // First check direct address match
14
+ const direct = this.model[address];
15
+ if (direct !== undefined) {
16
+ return direct;
17
+ }
18
+ // Check range: prefixed keys in model (from parsing large ranges)
19
+ // Only decode address if we have range keys to check
20
+ const keys = Object.keys(this.model);
21
+ const rangeKeys = keys.filter(k => k.startsWith("range:"));
22
+ if (rangeKeys.length === 0) {
23
+ return undefined;
24
+ }
25
+ const decoded = col_cache_js_1.colCache.decodeAddress(address);
26
+ for (const key of rangeKeys) {
27
+ const rangeStr = key.slice(6); // Remove "range:" prefix
28
+ const rangeDecoded = col_cache_js_1.colCache.decodeEx(rangeStr);
29
+ if (rangeDecoded.dimensions) {
30
+ const tl = rangeDecoded.tl;
31
+ const br = rangeDecoded.br;
32
+ if (decoded.row >= tl.row &&
33
+ decoded.row <= br.row &&
34
+ decoded.col >= tl.col &&
35
+ decoded.col <= br.col) {
36
+ return this.model[key];
37
+ }
38
+ }
39
+ }
40
+ return undefined;
13
41
  }
14
42
  remove(address) {
15
43
  this.model[address] = undefined;
@@ -30,7 +30,32 @@ function optimiseDataValidations(model) {
30
30
  if (!model) {
31
31
  return [];
32
32
  }
33
- const dvList = Object.entries(model)
33
+ // First, handle range: prefixed keys directly (large ranges stored during parsing)
34
+ const rangeValidations = [];
35
+ const regularModel = {};
36
+ for (const [key, value] of Object.entries(model)) {
37
+ // Skip undefined/null values (removed validations)
38
+ if (value === undefined || value === null) {
39
+ continue;
40
+ }
41
+ if (key.startsWith("range:")) {
42
+ // Large range stored during parsing - output directly
43
+ const rangeStr = key.slice(6); // Remove "range:" prefix
44
+ const { sqref: _sqref, ...rest } = value;
45
+ rangeValidations.push({
46
+ ...rest,
47
+ sqref: rangeStr
48
+ });
49
+ }
50
+ else {
51
+ regularModel[key] = value;
52
+ }
53
+ }
54
+ // If no regular entries, just return range validations
55
+ if (Object.keys(regularModel).length === 0) {
56
+ return rangeValidations;
57
+ }
58
+ const dvList = Object.entries(regularModel)
34
59
  .map(([address, dataValidation]) => ({
35
60
  address,
36
61
  dataValidation,
@@ -41,13 +66,14 @@ function optimiseDataValidations(model) {
41
66
  const matchCol = (addr, height, col) => {
42
67
  for (let i = 0; i < height; i++) {
43
68
  const otherAddress = col_cache_js_1.colCache.encodeAddress(addr.row + i, col);
44
- if (!model[otherAddress] || !(0, under_dash_js_1.isEqual)(model[addr.address], model[otherAddress])) {
69
+ if (!regularModel[otherAddress] ||
70
+ !(0, under_dash_js_1.isEqual)(regularModel[addr.address], regularModel[otherAddress])) {
45
71
  return false;
46
72
  }
47
73
  }
48
74
  return true;
49
75
  };
50
- return dvList
76
+ const optimized = dvList
51
77
  .map(dv => {
52
78
  if (!dv.marked) {
53
79
  const addr = col_cache_js_1.colCache.decodeEx(dv.address);
@@ -61,7 +87,8 @@ function optimiseDataValidations(model) {
61
87
  // iterate downwards - finding matching cells
62
88
  let height = 1;
63
89
  let otherAddress = col_cache_js_1.colCache.encodeAddress(addr.row + height, addr.col);
64
- while (model[otherAddress] && (0, under_dash_js_1.isEqual)(dv.dataValidation, model[otherAddress])) {
90
+ while (regularModel[otherAddress] &&
91
+ (0, under_dash_js_1.isEqual)(dv.dataValidation, regularModel[otherAddress])) {
65
92
  height++;
66
93
  otherAddress = col_cache_js_1.colCache.encodeAddress(addr.row + height, addr.col);
67
94
  }
@@ -93,6 +120,7 @@ function optimiseDataValidations(model) {
93
120
  return null;
94
121
  })
95
122
  .filter(Boolean);
123
+ return [...rangeValidations, ...optimized];
96
124
  }
97
125
  class DataValidationsXform extends base_xform_js_1.BaseXform {
98
126
  get tag() {
@@ -207,9 +235,20 @@ class DataValidationsXform extends base_xform_js_1.BaseXform {
207
235
  list.forEach((addr) => {
208
236
  if (addr.includes(":")) {
209
237
  const range = new range_js_1.Range(addr);
210
- range.forEachAddress((address) => {
211
- this.model[address] = this._dataValidation;
212
- });
238
+ // Only expand small ranges to avoid performance issues with large ranges
239
+ // like B2:B1048576 (entire column validations)
240
+ const rangeSize = (range.bottom - range.top + 1) * (range.right - range.left + 1);
241
+ if (rangeSize <= 1000) {
242
+ // Small range: expand to individual cells for backward compatibility
243
+ range.forEachAddress((address) => {
244
+ this.model[address] = this._dataValidation;
245
+ });
246
+ }
247
+ else {
248
+ // Large range: store as range string with special marker
249
+ // The key format "range:A1:Z100" allows DataValidations.find() to detect it
250
+ this.model[`range:${addr}`] = this._dataValidation;
251
+ }
213
252
  }
214
253
  else {
215
254
  this.model[addr] = this._dataValidation;
@@ -1,3 +1,4 @@
1
+ import { colCache } from "../utils/col-cache.js";
1
2
  class DataValidations {
2
3
  constructor(model) {
3
4
  this.model = model || {};
@@ -6,7 +7,34 @@ class DataValidations {
6
7
  return (this.model[address] = validation);
7
8
  }
8
9
  find(address) {
9
- return this.model[address];
10
+ // First check direct address match
11
+ const direct = this.model[address];
12
+ if (direct !== undefined) {
13
+ return direct;
14
+ }
15
+ // Check range: prefixed keys in model (from parsing large ranges)
16
+ // Only decode address if we have range keys to check
17
+ const keys = Object.keys(this.model);
18
+ const rangeKeys = keys.filter(k => k.startsWith("range:"));
19
+ if (rangeKeys.length === 0) {
20
+ return undefined;
21
+ }
22
+ const decoded = colCache.decodeAddress(address);
23
+ for (const key of rangeKeys) {
24
+ const rangeStr = key.slice(6); // Remove "range:" prefix
25
+ const rangeDecoded = colCache.decodeEx(rangeStr);
26
+ if (rangeDecoded.dimensions) {
27
+ const tl = rangeDecoded.tl;
28
+ const br = rangeDecoded.br;
29
+ if (decoded.row >= tl.row &&
30
+ decoded.row <= br.row &&
31
+ decoded.col >= tl.col &&
32
+ decoded.col <= br.col) {
33
+ return this.model[key];
34
+ }
35
+ }
36
+ }
37
+ return undefined;
10
38
  }
11
39
  remove(address) {
12
40
  this.model[address] = undefined;
@@ -27,7 +27,32 @@ function optimiseDataValidations(model) {
27
27
  if (!model) {
28
28
  return [];
29
29
  }
30
- const dvList = Object.entries(model)
30
+ // First, handle range: prefixed keys directly (large ranges stored during parsing)
31
+ const rangeValidations = [];
32
+ const regularModel = {};
33
+ for (const [key, value] of Object.entries(model)) {
34
+ // Skip undefined/null values (removed validations)
35
+ if (value === undefined || value === null) {
36
+ continue;
37
+ }
38
+ if (key.startsWith("range:")) {
39
+ // Large range stored during parsing - output directly
40
+ const rangeStr = key.slice(6); // Remove "range:" prefix
41
+ const { sqref: _sqref, ...rest } = value;
42
+ rangeValidations.push({
43
+ ...rest,
44
+ sqref: rangeStr
45
+ });
46
+ }
47
+ else {
48
+ regularModel[key] = value;
49
+ }
50
+ }
51
+ // If no regular entries, just return range validations
52
+ if (Object.keys(regularModel).length === 0) {
53
+ return rangeValidations;
54
+ }
55
+ const dvList = Object.entries(regularModel)
31
56
  .map(([address, dataValidation]) => ({
32
57
  address,
33
58
  dataValidation,
@@ -38,13 +63,14 @@ function optimiseDataValidations(model) {
38
63
  const matchCol = (addr, height, col) => {
39
64
  for (let i = 0; i < height; i++) {
40
65
  const otherAddress = colCache.encodeAddress(addr.row + i, col);
41
- if (!model[otherAddress] || !isEqual(model[addr.address], model[otherAddress])) {
66
+ if (!regularModel[otherAddress] ||
67
+ !isEqual(regularModel[addr.address], regularModel[otherAddress])) {
42
68
  return false;
43
69
  }
44
70
  }
45
71
  return true;
46
72
  };
47
- return dvList
73
+ const optimized = dvList
48
74
  .map(dv => {
49
75
  if (!dv.marked) {
50
76
  const addr = colCache.decodeEx(dv.address);
@@ -58,7 +84,8 @@ function optimiseDataValidations(model) {
58
84
  // iterate downwards - finding matching cells
59
85
  let height = 1;
60
86
  let otherAddress = colCache.encodeAddress(addr.row + height, addr.col);
61
- while (model[otherAddress] && isEqual(dv.dataValidation, model[otherAddress])) {
87
+ while (regularModel[otherAddress] &&
88
+ isEqual(dv.dataValidation, regularModel[otherAddress])) {
62
89
  height++;
63
90
  otherAddress = colCache.encodeAddress(addr.row + height, addr.col);
64
91
  }
@@ -90,6 +117,7 @@ function optimiseDataValidations(model) {
90
117
  return null;
91
118
  })
92
119
  .filter(Boolean);
120
+ return [...rangeValidations, ...optimized];
93
121
  }
94
122
  class DataValidationsXform extends BaseXform {
95
123
  get tag() {
@@ -204,9 +232,20 @@ class DataValidationsXform extends BaseXform {
204
232
  list.forEach((addr) => {
205
233
  if (addr.includes(":")) {
206
234
  const range = new Range(addr);
207
- range.forEachAddress((address) => {
208
- this.model[address] = this._dataValidation;
209
- });
235
+ // Only expand small ranges to avoid performance issues with large ranges
236
+ // like B2:B1048576 (entire column validations)
237
+ const rangeSize = (range.bottom - range.top + 1) * (range.right - range.left + 1);
238
+ if (rangeSize <= 1000) {
239
+ // Small range: expand to individual cells for backward compatibility
240
+ range.forEachAddress((address) => {
241
+ this.model[address] = this._dataValidation;
242
+ });
243
+ }
244
+ else {
245
+ // Large range: store as range string with special marker
246
+ // The key format "range:A1:Z100" allows DataValidations.find() to detect it
247
+ this.model[`range:${addr}`] = this._dataValidation;
248
+ }
210
249
  }
211
250
  else {
212
251
  this.model[addr] = this._dataValidation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cj-tech-master/excelts",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.",
5
5
  "private": false,
6
6
  "publishConfig": {