@microsoft/connected-workbooks 2.1.24-beta → 3.0.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.
Files changed (46) hide show
  1. package/README.md +25 -13
  2. package/dist/generators.js +1 -1
  3. package/dist/{GridParser.js → gridParser.js} +18 -8
  4. package/dist/gridUtils.js +58 -0
  5. package/dist/index.d.ts +2 -2
  6. package/dist/src/generators.js +14 -0
  7. package/dist/src/types.js +28 -0
  8. package/dist/src/utils/arrayUtils.js +46 -0
  9. package/dist/src/utils/constants.js +145 -0
  10. package/dist/src/utils/documentUtils.js +102 -0
  11. package/dist/src/utils/gridUtils.js +103 -0
  12. package/dist/src/utils/htmlUtils.js +19 -0
  13. package/dist/src/utils/index.js +24 -0
  14. package/dist/src/utils/mashupDocumentParser.js +145 -0
  15. package/dist/src/utils/pqUtils.js +100 -0
  16. package/dist/src/utils/tableUtils.js +143 -0
  17. package/dist/src/utils/xmlInnerPartsUtils.js +227 -0
  18. package/dist/src/utils/xmlPartsUtils.js +68 -0
  19. package/dist/src/workbookTemplate.js +7 -0
  20. package/dist/tests/arrayUtils.test.js +65 -0
  21. package/dist/tests/documentUtils.test.js +35 -0
  22. package/dist/tests/gridUtils.test.js +168 -0
  23. package/dist/tests/htmlUtils.test.js +109 -0
  24. package/dist/tests/mashupDocumentParser.test.js +59 -0
  25. package/dist/tests/mocks/PqMock.js +7 -0
  26. package/dist/tests/mocks/index.js +24 -0
  27. package/dist/tests/mocks/section1mSimpleQueryMock.js +18 -0
  28. package/dist/tests/mocks/xmlMocks.js +12 -0
  29. package/dist/tests/tableUtils.test.js +63 -0
  30. package/dist/tests/workbookQueryTemplate.test.js +64 -0
  31. package/dist/tests/workbookTableTemplate.test.js +54 -0
  32. package/dist/tests/xmlInnerPartsUtils.test.js +51 -0
  33. package/dist/types.d.ts +4 -1
  34. package/dist/utils/constants.js +20 -9
  35. package/dist/utils/documentUtils.js +9 -5
  36. package/dist/utils/gridUtils.js +103 -0
  37. package/dist/utils/htmlUtils.js +3 -3
  38. package/dist/utils/index.js +5 -1
  39. package/dist/utils/mashupDocumentParser.js +6 -24
  40. package/dist/utils/pqUtils.js +7 -4
  41. package/dist/utils/tableUtils.js +18 -19
  42. package/dist/utils/xmlInnerPartsUtils.js +38 -9
  43. package/dist/utils/xmlPartsUtils.js +12 -6
  44. package/dist/workbookManager.d.ts +3 -3
  45. package/dist/workbookManager.js +17 -22
  46. package/package.json +5 -3
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const types_1 = require("../types");
18
+ const constants_1 = require("./constants");
19
+ const documentUtils_1 = __importDefault(require("./documentUtils"));
20
+ const updateDocProps = (zip, docProps = {}) => __awaiter(void 0, void 0, void 0, function* () {
21
+ const { doc, properties } = yield documentUtils_1.default.getDocPropsProperties(zip);
22
+ //set auto updated elements
23
+ const docPropsAutoUpdatedElementsArr = Object.keys(types_1.DocPropsAutoUpdatedElements);
24
+ const nowTime = new Date().toISOString();
25
+ docPropsAutoUpdatedElementsArr.forEach((tag) => {
26
+ documentUtils_1.default.createOrUpdateProperty(doc, properties, types_1.DocPropsAutoUpdatedElements[tag], nowTime);
27
+ });
28
+ //set modifiable elements
29
+ const docPropsModifiableElementsArr = Object.keys(types_1.DocPropsModifiableElements);
30
+ docPropsModifiableElementsArr
31
+ .map((key) => ({
32
+ name: types_1.DocPropsModifiableElements[key],
33
+ value: docProps[key],
34
+ }))
35
+ .forEach((kvp) => {
36
+ documentUtils_1.default.createOrUpdateProperty(doc, properties, kvp.name, kvp.value);
37
+ });
38
+ const serializer = new XMLSerializer();
39
+ const newDoc = serializer.serializeToString(doc);
40
+ zip.file(constants_1.docPropsCoreXmlPath, newDoc);
41
+ });
42
+ const clearLabelInfo = (zip) => __awaiter(void 0, void 0, void 0, function* () {
43
+ var _a, _b, _c, _d;
44
+ // remove docMetadata folder that contains only LabelInfo.xml in template file.
45
+ zip.remove(constants_1.docMetadataXmlPath);
46
+ // fix rels
47
+ const relsString = yield ((_a = zip.file(constants_1.relsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
48
+ if (relsString === undefined) {
49
+ throw new Error(constants_1.relsNotFoundErr);
50
+ }
51
+ const parser = new DOMParser();
52
+ const doc = parser.parseFromString(relsString, constants_1.xmlTextResultType);
53
+ const relationships = doc.querySelector("Relationships");
54
+ if (relationships === null) {
55
+ throw new Error(constants_1.unexpectedErr);
56
+ }
57
+ const element = relationships.querySelector('Relationship[Target="docMetadata/LabelInfo.xml"]');
58
+ if (element) {
59
+ relationships.removeChild(element);
60
+ }
61
+ (_b = relationships.querySelector('Relationship[Target="xl/workbook.xml"]')) === null || _b === void 0 ? void 0 : _b.setAttribute("Id", "rId1");
62
+ (_c = relationships.querySelector('Relationship[Target="docProps/core.xml"]')) === null || _c === void 0 ? void 0 : _c.setAttribute("Id", "rId2");
63
+ (_d = relationships.querySelector('Relationship[Target="docProps/app.xml"]')) === null || _d === void 0 ? void 0 : _d.setAttribute("Id", "rId3");
64
+ const serializer = new XMLSerializer();
65
+ const newDoc = serializer.serializeToString(doc);
66
+ zip.file(constants_1.relsXmlPath, newDoc);
67
+ });
68
+ const updateConnections = (connectionsXmlString, queryName, refreshOnOpen) => {
69
+ var _a, _b, _c;
70
+ const parser = new DOMParser();
71
+ const serializer = new XMLSerializer();
72
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
73
+ const connectionsDoc = parser.parseFromString(connectionsXmlString, constants_1.xmlTextResultType);
74
+ const connectionsProperties = connectionsDoc.getElementsByTagName(constants_1.element.databaseProperties);
75
+ const dbPr = connectionsProperties[0];
76
+ dbPr.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
77
+ // Update query details to match queryName
78
+ (_a = dbPr.parentElement) === null || _a === void 0 ? void 0 : _a.setAttribute(constants_1.elementAttributes.name, constants_1.elementAttributesValues.connectionName(queryName));
79
+ (_b = dbPr.parentElement) === null || _b === void 0 ? void 0 : _b.setAttribute(constants_1.elementAttributes.description, constants_1.elementAttributesValues.connectionDescription(queryName));
80
+ dbPr.setAttribute(constants_1.elementAttributes.connection, constants_1.elementAttributesValues.connection(queryName));
81
+ dbPr.setAttribute(constants_1.elementAttributes.command, constants_1.elementAttributesValues.connectionCommand(queryName));
82
+ const connectionId = (_c = dbPr.parentElement) === null || _c === void 0 ? void 0 : _c.getAttribute(constants_1.elementAttributes.id);
83
+ const connectionXmlFileString = serializer.serializeToString(connectionsDoc);
84
+ if (connectionId === null) {
85
+ throw new Error(constants_1.connectionsNotFoundErr);
86
+ }
87
+ return { connectionId, connectionXmlFileString };
88
+ };
89
+ const updateSharedStrings = (sharedStringsXmlString, queryName) => {
90
+ const parser = new DOMParser();
91
+ const serializer = new XMLSerializer();
92
+ const sharedStringsDoc = parser.parseFromString(sharedStringsXmlString, constants_1.xmlTextResultType);
93
+ const sharedStringsTable = sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0];
94
+ if (!sharedStringsTable) {
95
+ throw new Error(constants_1.sharedStringsNotFoundErr);
96
+ }
97
+ const textElementCollection = sharedStringsDoc.getElementsByTagName(constants_1.element.text);
98
+ let textElement = null;
99
+ let sharedStringIndex = textElementCollection.length;
100
+ if (textElementCollection && textElementCollection.length) {
101
+ for (let i = 0; i < textElementCollection.length; i++) {
102
+ if (textElementCollection[i].innerHTML === queryName) {
103
+ textElement = textElementCollection[i];
104
+ sharedStringIndex = i + 1;
105
+ break;
106
+ }
107
+ }
108
+ }
109
+ if (textElement === null) {
110
+ if (sharedStringsDoc.documentElement.namespaceURI) {
111
+ textElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.text);
112
+ textElement.textContent = queryName;
113
+ const siElement = sharedStringsDoc.createElementNS(sharedStringsDoc.documentElement.namespaceURI, constants_1.element.sharedStringItem);
114
+ siElement.appendChild(textElement);
115
+ sharedStringsDoc.getElementsByTagName(constants_1.element.sharedStringTable)[0].appendChild(siElement);
116
+ }
117
+ const value = sharedStringsTable.getAttribute(constants_1.elementAttributes.count);
118
+ if (value) {
119
+ sharedStringsTable.setAttribute(constants_1.elementAttributes.count, (parseInt(value) + 1).toString());
120
+ }
121
+ const uniqueValue = sharedStringsTable.getAttribute(constants_1.elementAttributes.uniqueCount);
122
+ if (uniqueValue) {
123
+ sharedStringsTable.setAttribute(constants_1.elementAttributes.uniqueCount, (parseInt(uniqueValue) + 1).toString());
124
+ }
125
+ }
126
+ const newSharedStrings = serializer.serializeToString(sharedStringsDoc);
127
+ return { sharedStringIndex, newSharedStrings };
128
+ };
129
+ const updateWorksheet = (sheetsXmlString, sharedStringIndex) => {
130
+ const parser = new DOMParser();
131
+ const serializer = new XMLSerializer();
132
+ const sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
133
+ sheetsDoc.getElementsByTagName(constants_1.element.cellValue)[0].innerHTML = sharedStringIndex.toString();
134
+ const newSheet = serializer.serializeToString(sheetsDoc);
135
+ return newSheet;
136
+ };
137
+ const updatePivotTablesandQueryTables = (zip, queryName, refreshOnOpen, connectionId) => __awaiter(void 0, void 0, void 0, function* () {
138
+ var _e, _f;
139
+ // Find Query Table
140
+ let found = false;
141
+ const queryTablePromises = [];
142
+ (_e = zip.folder(constants_1.queryTablesPath)) === null || _e === void 0 ? void 0 : _e.forEach((relativePath, queryTableFile) => __awaiter(void 0, void 0, void 0, function* () {
143
+ queryTablePromises.push((() => {
144
+ return queryTableFile.async(constants_1.textResultType).then((queryTableString) => {
145
+ return {
146
+ path: relativePath,
147
+ queryTableXmlString: queryTableString,
148
+ };
149
+ });
150
+ })());
151
+ }));
152
+ (yield Promise.all(queryTablePromises)).forEach(({ path, queryTableXmlString }) => {
153
+ const { isQueryTableUpdated, newQueryTable } = updateQueryTable(queryTableXmlString, connectionId, refreshOnOpen);
154
+ zip.file(constants_1.queryTablesPath + path, newQueryTable);
155
+ if (isQueryTableUpdated) {
156
+ found = true;
157
+ }
158
+ });
159
+ if (found) {
160
+ return;
161
+ }
162
+ // Find Pivot Table
163
+ const pivotCachePromises = [];
164
+ (_f = zip.folder(constants_1.pivotCachesPath)) === null || _f === void 0 ? void 0 : _f.forEach((relativePath, pivotCacheFile) => __awaiter(void 0, void 0, void 0, function* () {
165
+ if (relativePath.startsWith(constants_1.pivotCachesPathPrefix)) {
166
+ pivotCachePromises.push((() => {
167
+ return pivotCacheFile.async(constants_1.textResultType).then((pivotCacheString) => {
168
+ return {
169
+ path: relativePath,
170
+ pivotCacheXmlString: pivotCacheString,
171
+ };
172
+ });
173
+ })());
174
+ }
175
+ }));
176
+ (yield Promise.all(pivotCachePromises)).forEach(({ path, pivotCacheXmlString }) => {
177
+ const { isPivotTableUpdated, newPivotTable } = updatePivotTable(pivotCacheXmlString, connectionId, refreshOnOpen);
178
+ zip.file(constants_1.pivotCachesPath + path, newPivotTable);
179
+ if (isPivotTableUpdated) {
180
+ found = true;
181
+ }
182
+ });
183
+ if (!found) {
184
+ throw new Error(constants_1.queryAndPivotTableNotFoundErr);
185
+ }
186
+ });
187
+ const updateQueryTable = (tableXmlString, connectionId, refreshOnOpen) => {
188
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
189
+ let isQueryTableUpdated = false;
190
+ const parser = new DOMParser();
191
+ const serializer = new XMLSerializer();
192
+ const queryTableDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
193
+ const queryTable = queryTableDoc.getElementsByTagName(constants_1.element.queryTable)[0];
194
+ let newQueryTable = constants_1.emptyValue;
195
+ if (queryTable.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
196
+ queryTable.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
197
+ newQueryTable = serializer.serializeToString(queryTableDoc);
198
+ isQueryTableUpdated = true;
199
+ }
200
+ return { isQueryTableUpdated, newQueryTable };
201
+ };
202
+ const updatePivotTable = (tableXmlString, connectionId, refreshOnOpen) => {
203
+ const refreshOnLoadValue = refreshOnOpen ? constants_1.trueValue : constants_1.falseValue;
204
+ let isPivotTableUpdated = false;
205
+ const parser = new DOMParser();
206
+ const serializer = new XMLSerializer();
207
+ const pivotCacheDoc = parser.parseFromString(tableXmlString, constants_1.xmlTextResultType);
208
+ let cacheSource = pivotCacheDoc.getElementsByTagName(constants_1.element.cacheSource)[0];
209
+ let newPivotTable = constants_1.emptyValue;
210
+ if (cacheSource.getAttribute(constants_1.elementAttributes.connectionId) == connectionId) {
211
+ cacheSource = cacheSource.parentElement;
212
+ cacheSource.setAttribute(constants_1.elementAttributes.refreshOnLoad, refreshOnLoadValue);
213
+ newPivotTable = serializer.serializeToString(pivotCacheDoc);
214
+ isPivotTableUpdated = true;
215
+ }
216
+ return { isPivotTableUpdated, newPivotTable };
217
+ };
218
+ exports.default = {
219
+ updateDocProps,
220
+ clearLabelInfo,
221
+ updateConnections,
222
+ updateSharedStrings,
223
+ updateWorksheet,
224
+ updatePivotTablesandQueryTables,
225
+ updateQueryTable,
226
+ updatePivotTable,
227
+ };
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6
+ return new (P || (P = Promise))(function (resolve, reject) {
7
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
10
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
11
+ });
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const constants_1 = require("./constants");
18
+ const mashupDocumentParser_1 = require("./mashupDocumentParser");
19
+ const pqUtils_1 = __importDefault(require("./pqUtils"));
20
+ const xmlInnerPartsUtils_1 = __importDefault(require("./xmlInnerPartsUtils"));
21
+ const tableUtils_1 = __importDefault(require("./tableUtils"));
22
+ const updateWorkbookDataAndConfigurations = (zip, fileConfigs, tableData, updateQueryTable = false) => __awaiter(void 0, void 0, void 0, function* () {
23
+ yield xmlInnerPartsUtils_1.default.updateDocProps(zip, fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.docProps);
24
+ if ((fileConfigs === null || fileConfigs === void 0 ? void 0 : fileConfigs.templateFile) === undefined) {
25
+ // If we are using our base template, we need to clear label info
26
+ yield xmlInnerPartsUtils_1.default.clearLabelInfo(zip);
27
+ }
28
+ yield tableUtils_1.default.updateTableInitialDataIfNeeded(zip, tableData, updateQueryTable);
29
+ });
30
+ const updateWorkbookPowerQueryDocument = (zip, queryName, queryMashupDoc) => __awaiter(void 0, void 0, void 0, function* () {
31
+ const old_base64 = yield pqUtils_1.default.getBase64(zip);
32
+ if (!old_base64) {
33
+ throw new Error(constants_1.base64NotFoundErr);
34
+ }
35
+ const new_base64 = yield (0, mashupDocumentParser_1.replaceSingleQuery)(old_base64, queryName, queryMashupDoc);
36
+ yield pqUtils_1.default.setBase64(zip, new_base64);
37
+ });
38
+ const updateWorkbookSingleQueryAttributes = (zip, queryName, refreshOnOpen) => __awaiter(void 0, void 0, void 0, function* () {
39
+ var _a, _b, _c;
40
+ // Update connections
41
+ const connectionsXmlString = yield ((_a = zip.file(constants_1.connectionsXmlPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType));
42
+ if (connectionsXmlString === undefined) {
43
+ throw new Error(constants_1.connectionsNotFoundErr);
44
+ }
45
+ const { connectionId, connectionXmlFileString } = xmlInnerPartsUtils_1.default.updateConnections(connectionsXmlString, queryName, refreshOnOpen);
46
+ zip.file(constants_1.connectionsXmlPath, connectionXmlFileString);
47
+ // Update sharedStrings
48
+ const sharedStringsXmlString = yield ((_b = zip.file(constants_1.sharedStringsXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType));
49
+ if (sharedStringsXmlString === undefined) {
50
+ throw new Error(constants_1.sharedStringsNotFoundErr);
51
+ }
52
+ const { sharedStringIndex, newSharedStrings } = xmlInnerPartsUtils_1.default.updateSharedStrings(sharedStringsXmlString, queryName);
53
+ zip.file(constants_1.sharedStringsXmlPath, newSharedStrings);
54
+ // Update sheet
55
+ const sheetsXmlString = yield ((_c = zip.file(constants_1.sheetsXmlPath)) === null || _c === void 0 ? void 0 : _c.async(constants_1.textResultType));
56
+ if (sheetsXmlString === undefined) {
57
+ throw new Error(constants_1.sheetsNotFoundErr);
58
+ }
59
+ const worksheetString = xmlInnerPartsUtils_1.default.updateWorksheet(sheetsXmlString, sharedStringIndex.toString());
60
+ zip.file(constants_1.sheetsXmlPath, worksheetString);
61
+ // Update tables
62
+ yield xmlInnerPartsUtils_1.default.updatePivotTablesandQueryTables(zip, queryName, refreshOnOpen, connectionId);
63
+ });
64
+ exports.default = {
65
+ updateWorkbookDataAndConfigurations,
66
+ updateWorkbookPowerQueryDocument,
67
+ updateWorkbookSingleQueryAttributes,
68
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.SIMPLE_BLANK_TABLE_TEMPLATE = exports.SIMPLE_QUERY_WORKBOOK_TEMPLATE = void 0;
6
+ exports.SIMPLE_QUERY_WORKBOOK_TEMPLATE = "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";
7
+ exports.SIMPLE_BLANK_TABLE_TEMPLATE = "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";
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ const utils_1 = require("../src/utils/");
29
+ const base64 = __importStar(require("base64-js"));
30
+ describe("ArrayReader tests", () => {
31
+ const buffer = base64.toByteArray("UHJhaXNlIFRoZSBTdW4h").buffer;
32
+ const arrReader = new utils_1.arrayUtils.ArrayReader(buffer);
33
+ test("getInt32 test", () => {
34
+ const int32 = arrReader.getInt32();
35
+ expect(int32).toEqual(1767993936);
36
+ expect(arrReader._position).toEqual(4);
37
+ });
38
+ test("getBytes test", () => {
39
+ const bytes = arrReader.getBytes(4);
40
+ expect(bytes).toEqual(new Uint8Array([115, 101, 32, 84]));
41
+ expect(arrReader._position).toEqual(8);
42
+ });
43
+ test("reset test", () => {
44
+ arrReader.reset();
45
+ expect(arrReader._position).toEqual(0);
46
+ });
47
+ });
48
+ test("getInt32Buffer test", () => {
49
+ const size = 4;
50
+ const val = 4;
51
+ const packageSizeBuffer = new ArrayBuffer(size);
52
+ new DataView(packageSizeBuffer).setInt32(0, val, true);
53
+ const expected = new Uint8Array(packageSizeBuffer);
54
+ const actual = utils_1.arrayUtils.getInt32Buffer(size);
55
+ expect(actual).toStrictEqual(expected);
56
+ });
57
+ test("concatArrays test", () => {
58
+ const uIntArr1 = new Uint8Array(4).fill(5);
59
+ const uIntArr2 = new Uint8Array(2).fill(10);
60
+ const expected = new Uint8Array(6);
61
+ expected.set(uIntArr1, 0);
62
+ expected.set(uIntArr2, 4);
63
+ const actual = utils_1.arrayUtils.concatArrays(uIntArr1, uIntArr2);
64
+ expect(actual).toStrictEqual(expected);
65
+ });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation.
3
+ // Licensed under the MIT license.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ const types_1 = require("../src/types");
6
+ const utils_1 = require("../src/utils");
7
+ describe("Document Utils tests", () => {
8
+ test("ResolveType date not supported success", () => {
9
+ expect(utils_1.documentUtils.resolveType("5-4-2023 00:00", false)).toEqual(types_1.DataTypes.string);
10
+ });
11
+ test("ResolveType string success", () => {
12
+ expect(utils_1.documentUtils.resolveType("sTrIng", false)).toEqual(types_1.DataTypes.string);
13
+ expect(utils_1.documentUtils.resolveType("True", false)).toEqual(types_1.DataTypes.string);
14
+ expect(utils_1.documentUtils.resolveType("False", false)).toEqual(types_1.DataTypes.string);
15
+ });
16
+ test("ResolveType boolean success", () => {
17
+ expect(utils_1.documentUtils.resolveType("true", false)).toEqual(types_1.DataTypes.boolean);
18
+ expect(utils_1.documentUtils.resolveType(" true", false)).toEqual(types_1.DataTypes.boolean);
19
+ expect(utils_1.documentUtils.resolveType("false", false)).toEqual(types_1.DataTypes.boolean);
20
+ expect(utils_1.documentUtils.resolveType(" false", false)).toEqual(types_1.DataTypes.boolean);
21
+ });
22
+ test("ResolveType number success", () => {
23
+ expect(utils_1.documentUtils.resolveType("100000", false)).toEqual(types_1.DataTypes.number);
24
+ expect(utils_1.documentUtils.resolveType("1000.00", false)).toEqual(types_1.DataTypes.number);
25
+ expect(utils_1.documentUtils.resolveType("1000.50", false)).toEqual(types_1.DataTypes.number);
26
+ expect(utils_1.documentUtils.resolveType("1000.50", false)).toEqual(types_1.DataTypes.number);
27
+ expect(utils_1.documentUtils.resolveType("1.23450", false)).toEqual(types_1.DataTypes.number);
28
+ expect(utils_1.documentUtils.resolveType("1.23.4.50", false)).toEqual(types_1.DataTypes.string);
29
+ });
30
+ test("ResolveType header row success", () => {
31
+ expect(utils_1.documentUtils.resolveType("100000", true)).toEqual(types_1.DataTypes.string);
32
+ expect(utils_1.documentUtils.resolveType("true", true)).toEqual(types_1.DataTypes.string);
33
+ expect(utils_1.documentUtils.resolveType("string", true)).toEqual(types_1.DataTypes.string);
34
+ });
35
+ });