abstract-sheet 1.2.3 → 1.3.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 +10 -0
- package/lib/abstract-sheet-exporters/xlsx.js.map +1 -1
- package/lib/abstract-sheet-xml/abstract-sheet-xml.d.ts.map +1 -1
- package/lib/abstract-sheet-xml/abstract-sheet-xml.js +23 -11
- package/lib/abstract-sheet-xml/abstract-sheet-xml.js.map +1 -1
- package/package.json +6 -3
- package/src/abstract-sheet-exporters/xlsx.ts +1 -1
- package/src/abstract-sheet-xml/abstract-sheet-xml.test.ts +56 -0
- package/src/abstract-sheet-xml/abstract-sheet-xml.ts +26 -12
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [1.3.1] - 2026-09-14
|
|
6
|
+
|
|
7
|
+
- Fixed: `<ColInfo>`/`<RowInfo>` XML template elements' `widthPixels`/`heightPixels`/`hidden` attributes are now parsed into real numbers/booleans instead of staying raw strings; previously a non-empty string was never falsy/nullish, so the default width/height fallback never applied and `hidden="false"` was written to the spreadsheet as hidden.
|
|
8
|
+
- Fixed: `<Cell>`'s boolean attribute is now read as `bool`, matching the XSD; it was previously read as `boolean`, so a schema-valid `<Cell bool="true"/>` silently produced an empty string cell instead of a boolean cell.
|
|
9
|
+
|
|
10
|
+
## [1.3.0] - 2026-09-10
|
|
11
|
+
|
|
12
|
+
- Changed: an XML template attribute written without a value (e.g. `<Cell boolean>` instead of `boolean="true"`) no longer takes effect — see handlebars-xml's changelog for why; always give attributes an explicit value.
|
|
13
|
+
- Internal: activated `typescript/no-unnecessary-condition`. Added a vitest project and first tests for this package (previously untested).
|
|
14
|
+
|
|
5
15
|
## [1.2.0] - 2026-09-06
|
|
6
16
|
|
|
7
17
|
- Internal: activated 39 additional oxlint rules — curly, default-case, eqeqeq, init-declarations, no-alert, no-bitwise, no-case-declarations, no-empty-pattern, no-prototype-builtins, no-restricted-globals, no-restricted-properties, no-shadow, no-throw-literal, no-unused-vars, no-useless-return, node/global-require, one-var, prefer-const, prefer-object-spread, typescript/array-type, typescript/ban-tslint-comment, typescript/dot-notation, typescript/explicit-module-boundary-types, typescript/no-empty-object-type, typescript/no-explicit-any, typescript/no-require-imports, typescript/no-unnecessary-boolean-literal-compare, typescript/no-var-requires, typescript/no-wrapper-object-types, typescript/parameter-properties, typescript/prefer-nullish-coalescing, typescript/prefer-optional-chain, typescript/prefer-readonly, typescript/prefer-reduce-type-parameter, typescript/prefer-string-starts-ends-with, typescript/switch-exhaustiveness-check, typescript/unified-signatures, unicorn/no-array-sort — and upgraded `oxlint-config-divid` to 1.2.0. No functional changes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xlsx.js","sourceRoot":"","sources":["../../src/abstract-sheet-exporters/xlsx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,IAAI,MAAM,eAAe,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,MAAM,CAAC,EAAiB;IACtC,MAAM,MAAM,GAAmC,EAAE,CAAC;IAElD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzF,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,EAAE,GAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IAE9E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;QAC5B,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,KAAK;KACjB,
|
|
1
|
+
{"version":3,"file":"xlsx.js","sourceRoot":"","sources":["../../src/abstract-sheet-exporters/xlsx.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,IAAI,MAAM,eAAe,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,UAAU,MAAM,CAAC,EAAiB;IACtC,MAAM,MAAM,GAAmC,EAAE,CAAC;IAElD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACzF,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,EAAE,GAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IAE9E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE;QAC5B,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,KAAK;KACjB,CAA4B,CAAC;IAE9B,mDAAmD;IACnD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,8CAA8C;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,wBAAwB,GAAG,iDAAiD,CAAC;AAEnF,MAAM,wBAAwB,GAC5B,6HAA6H,CAAC;AAEhI,SAAS,cAAc,CAAC,UAAmC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9D,OAAO,QAAQ,CAAC,iBAAiB,CAAC,CAAC;IAEnC,MAAM,eAAe,GAAG,qBAAqB,CAAC;IAE9C,IAAI,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC9B,IAAI,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;QAEvE,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;QAClE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,OAAO,GAAG,4BAA4B,CAAC;IAE7C,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACtB,IAAI,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;QAElD,QAAQ,CAAC,OAAO,CAAC,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAExD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-sheet-xml.d.ts","sourceRoot":"","sources":["../../src/abstract-sheet-xml/abstract-sheet-xml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"abstract-sheet-xml.d.ts","sourceRoot":"","sources":["../../src/abstract-sheet-xml/abstract-sheet-xml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,KAAK,EAAqE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAG5I,eAAO,MAAM,gBAAgB,aAAc,MAAM,QAAQ,OAAO,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,aACP,CAAC;AAwI/F,eAAO,MAAM,SAAS,uBAAgB,CAAC"}
|
|
@@ -5,11 +5,9 @@ export const abstractSheetXml = (template, data, partials) => abstractSheetXmlRe
|
|
|
5
5
|
function abstractSheetXmlRecursive(el) {
|
|
6
6
|
const children = Array();
|
|
7
7
|
const childElements = Array();
|
|
8
|
-
for (const child of el.children
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
childElements.push(child);
|
|
12
|
-
}
|
|
8
|
+
for (const child of el.children) {
|
|
9
|
+
children.push(abstractSheetXmlRecursive(child));
|
|
10
|
+
childElements.push(child);
|
|
13
11
|
}
|
|
14
12
|
switch (el.tagName) {
|
|
15
13
|
case "AbstractSheet": {
|
|
@@ -41,21 +39,27 @@ function abstractSheetXmlRecursive(el) {
|
|
|
41
39
|
}
|
|
42
40
|
});
|
|
43
41
|
return {
|
|
44
|
-
name: (el.attributes
|
|
42
|
+
name: (el.attributes.name ?? ""),
|
|
45
43
|
cells,
|
|
46
44
|
colInfo,
|
|
47
45
|
rowInfo,
|
|
48
|
-
direction: (el.attributes
|
|
46
|
+
direction: (el.attributes.direction ?? ""),
|
|
49
47
|
};
|
|
50
48
|
}
|
|
51
49
|
case "ColInfos":
|
|
52
50
|
return children;
|
|
53
51
|
case "ColInfo":
|
|
54
|
-
return
|
|
52
|
+
return {
|
|
53
|
+
hidden: strToBool(el.attributes["hidden"]),
|
|
54
|
+
widthPixels: strToNum(el.attributes["widthPixels"]),
|
|
55
|
+
};
|
|
55
56
|
case "RowInfos":
|
|
56
57
|
return children;
|
|
57
58
|
case "RowInfo":
|
|
58
|
-
return
|
|
59
|
+
return {
|
|
60
|
+
hidden: strToBool(el.attributes["hidden"]),
|
|
61
|
+
heightPixels: strToNum(el.attributes["heightPixels"]),
|
|
62
|
+
};
|
|
59
63
|
case "Cells":
|
|
60
64
|
return children;
|
|
61
65
|
case "Cell": {
|
|
@@ -65,8 +69,8 @@ function abstractSheetXmlRecursive(el) {
|
|
|
65
69
|
const num = Number.isNaN(parsedNumber) ? el.attributes["number"] : parsedNumber;
|
|
66
70
|
return { ...el.attributes, type: "number", value: num, styles };
|
|
67
71
|
}
|
|
68
|
-
else if (el.attributes["
|
|
69
|
-
return { ...el.attributes, type: "boolean", value: el.attributes["
|
|
72
|
+
else if (el.attributes["bool"] !== undefined) {
|
|
73
|
+
return { ...el.attributes, type: "boolean", value: el.attributes["bool"], styles };
|
|
70
74
|
}
|
|
71
75
|
else if (el.attributes["date"] !== undefined) {
|
|
72
76
|
return { ...el.attributes, type: "date", value: el.attributes["date"], styles };
|
|
@@ -126,5 +130,13 @@ function abstractSheetXmlRecursive(el) {
|
|
|
126
130
|
throw new Error(`Could not find creator for element with name ${el.tagName}`);
|
|
127
131
|
}
|
|
128
132
|
}
|
|
133
|
+
const strToBool = (str) => (str === undefined ? undefined : str === "true" || str === "1");
|
|
134
|
+
const strToNum = (str) => {
|
|
135
|
+
if (str === undefined) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const num = Number(str);
|
|
139
|
+
return Number.isFinite(num) ? num : undefined;
|
|
140
|
+
};
|
|
129
141
|
export const parsedXsd = parseXsd(xsd);
|
|
130
142
|
//# sourceMappingURL=abstract-sheet-xml.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstract-sheet-xml.js","sourceRoot":"","sources":["../../src/abstract-sheet-xml/abstract-sheet-xml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,yCAAyC,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAExE,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,IAAa,EAAE,QAAgC,EAAiB,EAAE,CACnH,yBAAyB,CAAC,kBAAkB,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAE,CAAkB,CAAC;AAE/F,SAAS,yBAAyB,CAAC,EAAc;IAC/C,MAAM,QAAQ,GAAG,KAAK,EAAW,CAAC;IAClC,MAAM,aAAa,GAAG,KAAK,EAAc,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"abstract-sheet-xml.js","sourceRoot":"","sources":["../../src/abstract-sheet-xml/abstract-sheet-xml.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abstract-sheet",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"gitHead": "
|
|
3
|
+
"version": "1.3.1",
|
|
4
|
+
"gitHead": "d33473932aad0f8a1741bfbad4754a41460b9972",
|
|
5
5
|
"description": "Abstract sheet",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Divid AB <info@divid.se>",
|
|
@@ -20,11 +20,14 @@
|
|
|
20
20
|
"exports": {
|
|
21
21
|
".": "./lib/index.js"
|
|
22
22
|
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "vitest run src/**/*.test.ts"
|
|
25
|
+
},
|
|
23
26
|
"dependencies": {
|
|
24
27
|
"fast-xml-parser": "^4.5.0",
|
|
25
28
|
"fflate": "^0.8.0",
|
|
26
29
|
"handlebars": "4.7.8",
|
|
27
|
-
"handlebars-xml": "^0.
|
|
30
|
+
"handlebars-xml": "^0.6.1",
|
|
28
31
|
"moment": "^2.30.1",
|
|
29
32
|
"ts-exhaustive-check": "^1.0.0",
|
|
30
33
|
"xlsx-js-style": "^1.2.0"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { abstractSheetXml } from "./abstract-sheet-xml.js";
|
|
3
|
+
|
|
4
|
+
describe("abstractSheetXml", () => {
|
|
5
|
+
it("extracts the Sheet name and direction attributes", () => {
|
|
6
|
+
const result = abstractSheetXml('<AbstractSheet><Sheet name="Sheet1" direction="row"><Cells></Cells></Sheet></AbstractSheet>', {}, {});
|
|
7
|
+
expect(result.sheets[0]).toMatchObject({ name: "Sheet1", direction: "row" });
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("falls back to an empty name/direction when the attributes are absent", () => {
|
|
11
|
+
const result = abstractSheetXml("<AbstractSheet><Sheet><Cells></Cells></Sheet></AbstractSheet>", {}, {});
|
|
12
|
+
expect(result.sheets[0]).toMatchObject({ name: "", direction: "" });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("recurses into a Sheet's children (ColInfos/RowInfos/Cells) without needing a null-check", () => {
|
|
16
|
+
const result = abstractSheetXml(
|
|
17
|
+
'<AbstractSheet><Sheet name="Sheet1"><ColInfos><ColInfo widthPixels="100" /></ColInfos><RowInfos><RowInfo heightPixels="20" /></RowInfos><Cells><Cell text="hello" /></Cells></Sheet></AbstractSheet>',
|
|
18
|
+
{},
|
|
19
|
+
{}
|
|
20
|
+
);
|
|
21
|
+
const [sheet] = result.sheets;
|
|
22
|
+
expect(sheet.colInfo).toEqual([{ widthPixels: 100 }]);
|
|
23
|
+
expect(sheet.rowInfo).toEqual([{ heightPixels: 20 }]);
|
|
24
|
+
expect(sheet.cells).toEqual([[{ text: "hello", type: "string", value: "hello", styles: undefined }]]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('coerces ColInfo/RowInfo hidden to a real boolean, not the truthy string "false"', () => {
|
|
28
|
+
const result = abstractSheetXml(
|
|
29
|
+
'<AbstractSheet><Sheet name="Sheet1"><ColInfos><ColInfo hidden="false" /></ColInfos><RowInfos><RowInfo hidden="true" /></RowInfos><Cells></Cells></Sheet></AbstractSheet>',
|
|
30
|
+
{},
|
|
31
|
+
{}
|
|
32
|
+
);
|
|
33
|
+
const [sheet] = result.sheets;
|
|
34
|
+
expect(sheet.colInfo).toEqual([{ hidden: false }]);
|
|
35
|
+
expect(sheet.rowInfo).toEqual([{ hidden: true }]);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('parses a Cell\'s "bool" attribute (matching the XSD) as a boolean-typed cell', () => {
|
|
39
|
+
const result = abstractSheetXml('<AbstractSheet><Sheet name="Sheet1"><Cells><Cell bool="true" /></Cells></Sheet></AbstractSheet>', {}, {});
|
|
40
|
+
expect(result.sheets[0]?.cells).toEqual([[{ bool: "true", type: "boolean", value: "true", styles: undefined }]]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("handles a Sheet with no children at all", () => {
|
|
44
|
+
const result = abstractSheetXml('<AbstractSheet><Sheet name="Empty" /></AbstractSheet>', {}, {});
|
|
45
|
+
expect(result.sheets[0]).toMatchObject({ name: "Empty", cells: [], colInfo: undefined, rowInfo: undefined });
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("handles multiple sheets, each recursing through its own children", () => {
|
|
49
|
+
const result = abstractSheetXml(
|
|
50
|
+
'<AbstractSheet><Sheet name="A"><Cells></Cells></Sheet><Sheet name="B"><Cells></Cells></Sheet></AbstractSheet>',
|
|
51
|
+
{},
|
|
52
|
+
{}
|
|
53
|
+
);
|
|
54
|
+
expect(result.sheets.map((s) => s.name)).toEqual(["A", "B"]);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { XmlElement } from "handlebars-xml";
|
|
2
2
|
import { parseHandlebarsXml, parseXsd } from "handlebars-xml";
|
|
3
3
|
import { xsd } from "../abstract-sheet/abstract-sheet-xsd.js";
|
|
4
|
-
import type { ColInfos, Cells, RowInfos, Sheet, Style, Styles, AbstractSheet } from "../abstract-sheet/abstract-sheet.js";
|
|
4
|
+
import type { ColInfo, ColInfos, Cells, RowInfo, RowInfos, Sheet, Style, Styles, AbstractSheet } from "../abstract-sheet/abstract-sheet.js";
|
|
5
5
|
import { borderStyleRecord } from "../abstract-sheet/abstract-sheet.js";
|
|
6
6
|
|
|
7
7
|
export const abstractSheetXml = (template: string, data: unknown, partials: Record<string, string>): AbstractSheet =>
|
|
@@ -10,11 +10,9 @@ export const abstractSheetXml = (template: string, data: unknown, partials: Reco
|
|
|
10
10
|
function abstractSheetXmlRecursive(el: XmlElement): unknown {
|
|
11
11
|
const children = Array<unknown>();
|
|
12
12
|
const childElements = Array<XmlElement>();
|
|
13
|
-
for (const child of el.children
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
childElements.push(child);
|
|
17
|
-
}
|
|
13
|
+
for (const child of el.children) {
|
|
14
|
+
children.push(abstractSheetXmlRecursive(child));
|
|
15
|
+
childElements.push(child);
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
switch (el.tagName) {
|
|
@@ -44,21 +42,27 @@ function abstractSheetXmlRecursive(el: XmlElement): unknown {
|
|
|
44
42
|
}
|
|
45
43
|
});
|
|
46
44
|
return {
|
|
47
|
-
name: ((el.attributes as Partial<Record<keyof Sheet, unknown>>)
|
|
45
|
+
name: ((el.attributes as Partial<Record<keyof Sheet, unknown>>).name ?? "") as string,
|
|
48
46
|
cells,
|
|
49
47
|
colInfo,
|
|
50
48
|
rowInfo,
|
|
51
|
-
direction: ((el.attributes as Partial<Record<keyof Sheet, unknown>>)
|
|
49
|
+
direction: ((el.attributes as Partial<Record<keyof Sheet, unknown>>).direction ?? "") as Sheet["direction"],
|
|
52
50
|
} satisfies Sheet;
|
|
53
51
|
}
|
|
54
52
|
case "ColInfos":
|
|
55
53
|
return children;
|
|
56
54
|
case "ColInfo":
|
|
57
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
hidden: strToBool(el.attributes["hidden"]),
|
|
57
|
+
widthPixels: strToNum(el.attributes["widthPixels"]),
|
|
58
|
+
} satisfies ColInfo;
|
|
58
59
|
case "RowInfos":
|
|
59
60
|
return children;
|
|
60
61
|
case "RowInfo":
|
|
61
|
-
return
|
|
62
|
+
return {
|
|
63
|
+
hidden: strToBool(el.attributes["hidden"]),
|
|
64
|
+
heightPixels: strToNum(el.attributes["heightPixels"]),
|
|
65
|
+
} satisfies RowInfo;
|
|
62
66
|
case "Cells":
|
|
63
67
|
return children;
|
|
64
68
|
case "Cell": {
|
|
@@ -67,8 +71,8 @@ function abstractSheetXmlRecursive(el: XmlElement): unknown {
|
|
|
67
71
|
const parsedNumber = Number(el.attributes["number"]);
|
|
68
72
|
const num = Number.isNaN(parsedNumber) ? el.attributes["number"] : parsedNumber;
|
|
69
73
|
return { ...el.attributes, type: "number", value: num, styles };
|
|
70
|
-
} else if (el.attributes["
|
|
71
|
-
return { ...el.attributes, type: "boolean", value: el.attributes["
|
|
74
|
+
} else if (el.attributes["bool"] !== undefined) {
|
|
75
|
+
return { ...el.attributes, type: "boolean", value: el.attributes["bool"], styles };
|
|
72
76
|
} else if (el.attributes["date"] !== undefined) {
|
|
73
77
|
return { ...el.attributes, type: "date", value: el.attributes["date"], styles };
|
|
74
78
|
} else {
|
|
@@ -127,4 +131,14 @@ function abstractSheetXmlRecursive(el: XmlElement): unknown {
|
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
const strToBool = (str: string | undefined): boolean | undefined => (str === undefined ? undefined : str === "true" || str === "1");
|
|
135
|
+
|
|
136
|
+
const strToNum = (str: string | undefined): number | undefined => {
|
|
137
|
+
if (str === undefined) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
const num = Number(str);
|
|
141
|
+
return Number.isFinite(num) ? num : undefined;
|
|
142
|
+
};
|
|
143
|
+
|
|
130
144
|
export const parsedXsd = parseXsd(xsd);
|