@microsoft/connected-workbooks 3.2.2-beta → 3.3.2-beta
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/README.md +372 -132
- package/dist/src/utils/constants.js +20 -2
- package/dist/src/utils/documentUtils.js +18 -4
- package/dist/src/utils/tableUtils.js +74 -29
- package/dist/src/utils/xmlInnerPartsUtils.js +156 -14
- package/dist/src/utils/xmlPartsUtils.js +61 -17
- package/dist/src/workbookTemplate.js +3 -1
- package/dist/tests/arrayUtils.test.js +14 -13
- package/dist/tests/documentUtils.test.js +40 -34
- package/dist/tests/gridUtils.test.js +59 -13
- package/dist/tests/htmlUtils.test.js +16 -15
- package/dist/tests/mashupDocumentParser.test.js +7 -6
- package/dist/tests/mocks/xmlMocks.js +3 -1
- package/dist/tests/tableUtils.test.js +44 -37
- package/dist/tests/workbookQueryTemplate.test.js +89 -17
- package/dist/tests/workbookTableTemplate.test.js +12 -11
- package/dist/tests/xmlInnerPartsUtils.test.js +159 -18
- package/dist/types.d.ts +7 -1
- package/dist/utils/constants.js +20 -2
- package/dist/utils/documentUtils.js +18 -4
- package/dist/utils/tableUtils.js +74 -29
- package/dist/utils/xmlInnerPartsUtils.js +156 -14
- package/dist/utils/xmlPartsUtils.js +61 -17
- package/dist/workbookManager.js +12 -12
- package/dist/workbookTemplate.js +3 -1
- package/package.json +8 -2
|
@@ -37,94 +37,235 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
37
37
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
40
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
44
|
var mocks_1 = require("./mocks");
|
|
42
45
|
var utils_1 = require("../src/utils");
|
|
43
|
-
|
|
46
|
+
var globals_1 = require("@jest/globals");
|
|
47
|
+
var jszip_1 = __importDefault(require("jszip"));
|
|
48
|
+
var workbookTemplate_1 = require("../src/workbookTemplate");
|
|
49
|
+
(0, globals_1.describe)("Workbook Manager tests", function () {
|
|
44
50
|
var mockConnectionString = "<connections xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" mc:Ignorable=\"xr16\">\n <connection id=\"1\" xr16:uid=\"{86BA784C-6640-4989-A85E-EB4966B9E741}\" keepAlive=\"1\" name=\"Query - Query1\" description=\"Connection to the 'Query1' query in the workbook.\" type=\"5\" refreshedVersion=\"7\" background=\"1\" saveData=\"1\">\n <dbPr connection=\"Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Query1;\" command=\"SELECT * FROM [Query1]\"/></connection></connections>";
|
|
45
|
-
test("Connection XML attributes contain new query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
51
|
+
(0, globals_1.test)("Connection XML attributes contain new query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
46
52
|
var connectionXmlFileString;
|
|
47
53
|
return __generator(this, function (_a) {
|
|
48
54
|
switch (_a.label) {
|
|
49
55
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateConnections(mockConnectionString, "newQueryName", true)];
|
|
50
56
|
case 1:
|
|
51
57
|
connectionXmlFileString = (_a.sent()).connectionXmlFileString;
|
|
52
|
-
expect(connectionXmlFileString.replace(/ /g, "")).toContain('command="SELECT * FROM [newQueryName]'.replace(/ /g, ""));
|
|
53
|
-
expect(connectionXmlFileString.replace(/ /g, "")).toContain('name="Query - newQueryName"'.replace(/ /g, ""));
|
|
54
|
-
expect(connectionXmlFileString.replace(/ /g, "")).toContain("description=\"Connection to the 'newQueryName' query in the workbook.\"".replace(/ /g, ""));
|
|
58
|
+
(0, globals_1.expect)(connectionXmlFileString.replace(/ /g, "")).toContain('command="SELECT * FROM [newQueryName]'.replace(/ /g, ""));
|
|
59
|
+
(0, globals_1.expect)(connectionXmlFileString.replace(/ /g, "")).toContain('name="Query - newQueryName"'.replace(/ /g, ""));
|
|
60
|
+
(0, globals_1.expect)(connectionXmlFileString.replace(/ /g, "")).toContain("description=\"Connection to the 'newQueryName' query in the workbook.\"".replace(/ /g, ""));
|
|
55
61
|
return [2 /*return*/];
|
|
56
62
|
}
|
|
57
63
|
});
|
|
58
64
|
}); });
|
|
59
|
-
test("Connection XML attributes contain refreshOnLoad value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
65
|
+
(0, globals_1.test)("Connection XML attributes contain refreshOnLoad value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
60
66
|
var connectionXmlFileString;
|
|
61
67
|
return __generator(this, function (_a) {
|
|
62
68
|
switch (_a.label) {
|
|
63
69
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateConnections(mockConnectionString, "newQueryName", true)];
|
|
64
70
|
case 1:
|
|
65
71
|
connectionXmlFileString = (_a.sent()).connectionXmlFileString;
|
|
66
|
-
expect(connectionXmlFileString.replace(/ /g, "")).toContain('refreshOnLoad="1"');
|
|
72
|
+
(0, globals_1.expect)(connectionXmlFileString.replace(/ /g, "")).toContain('refreshOnLoad="1"');
|
|
67
73
|
return [2 /*return*/];
|
|
68
74
|
}
|
|
69
75
|
});
|
|
70
76
|
}); });
|
|
71
|
-
test("SharedStrings XML contains new query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
77
|
+
(0, globals_1.test)("SharedStrings XML contains new query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
72
78
|
var newSharedStrings;
|
|
73
79
|
return __generator(this, function (_a) {
|
|
74
80
|
switch (_a.label) {
|
|
75
81
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName")];
|
|
76
82
|
case 1:
|
|
77
83
|
newSharedStrings = (_a.sent()).newSharedStrings;
|
|
78
|
-
expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
|
|
84
|
+
(0, globals_1.expect)(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
|
|
79
85
|
return [2 /*return*/];
|
|
80
86
|
}
|
|
81
87
|
});
|
|
82
88
|
}); });
|
|
83
|
-
test("Tests SharedStrings update when XML contains query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
89
|
+
(0, globals_1.test)("Tests SharedStrings update when XML contains query name", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
84
90
|
var newSharedStrings;
|
|
85
91
|
return __generator(this, function (_a) {
|
|
86
92
|
switch (_a.label) {
|
|
87
93
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>newQueryName</t></si><si><t/></si></sst>', "newQueryName")];
|
|
88
94
|
case 1:
|
|
89
95
|
newSharedStrings = (_a.sent()).newSharedStrings;
|
|
90
|
-
expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.existingSharedStringsXmlMock.replace(/ /g, ""));
|
|
96
|
+
(0, globals_1.expect)(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.existingSharedStringsXmlMock.replace(/ /g, ""));
|
|
91
97
|
return [2 /*return*/];
|
|
92
98
|
}
|
|
93
99
|
});
|
|
94
100
|
}); });
|
|
95
|
-
test("SharedStrings XML returns new index", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
101
|
+
(0, globals_1.test)("SharedStrings XML returns new index", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
96
102
|
var sharedStringIndex;
|
|
97
103
|
return __generator(this, function (_a) {
|
|
98
104
|
switch (_a.label) {
|
|
99
105
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName")];
|
|
100
106
|
case 1:
|
|
101
107
|
sharedStringIndex = (_a.sent()).sharedStringIndex;
|
|
102
|
-
expect(sharedStringIndex).toEqual(2);
|
|
108
|
+
(0, globals_1.expect)(sharedStringIndex).toEqual(2);
|
|
103
109
|
return [2 /*return*/];
|
|
104
110
|
}
|
|
105
111
|
});
|
|
106
112
|
}); });
|
|
107
|
-
test("SharedStrings XML returns existing index", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
113
|
+
(0, globals_1.test)("SharedStrings XML returns existing index", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
108
114
|
var sharedStringIndex;
|
|
109
115
|
return __generator(this, function (_a) {
|
|
110
116
|
switch (_a.label) {
|
|
111
117
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>newQueryName</t></si><si><t/></si></sst>', "newQueryName")];
|
|
112
118
|
case 1:
|
|
113
119
|
sharedStringIndex = (_a.sent()).sharedStringIndex;
|
|
114
|
-
expect(sharedStringIndex).toEqual(1);
|
|
120
|
+
(0, globals_1.expect)(sharedStringIndex).toEqual(1);
|
|
115
121
|
return [2 /*return*/];
|
|
116
122
|
}
|
|
117
123
|
});
|
|
118
124
|
}); });
|
|
119
|
-
test("Table XML contains refrshonload value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
125
|
+
(0, globals_1.test)("Table XML contains refrshonload value", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
120
126
|
var _a, sharedStringIndex, newSharedStrings;
|
|
121
127
|
return __generator(this, function (_b) {
|
|
122
128
|
switch (_b.label) {
|
|
123
129
|
case 0: return [4 /*yield*/, utils_1.xmlInnerPartsUtils.updateSharedStrings('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="1" uniqueCount="1"><si><t>Query1</t></si><si><t/></si></sst>', "newQueryName")];
|
|
124
130
|
case 1:
|
|
125
131
|
_a = _b.sent(), sharedStringIndex = _a.sharedStringIndex, newSharedStrings = _a.newSharedStrings;
|
|
126
|
-
expect(sharedStringIndex).toEqual(2);
|
|
127
|
-
expect(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
|
|
132
|
+
(0, globals_1.expect)(sharedStringIndex).toEqual(2);
|
|
133
|
+
(0, globals_1.expect)(newSharedStrings.replace(/ /g, "")).toContain(mocks_1.sharedStringsXmlMock.replace(/ /g, ""));
|
|
134
|
+
return [2 /*return*/];
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}); });
|
|
138
|
+
(0, globals_1.test)("Table XML contains correct Table reference value with headers included", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
139
|
+
var singleTableDefaultTemplate, defaultZipFile, data, tableData, _a;
|
|
140
|
+
var _b;
|
|
141
|
+
return __generator(this, function (_c) {
|
|
142
|
+
switch (_c.label) {
|
|
143
|
+
case 0:
|
|
144
|
+
singleTableDefaultTemplate = workbookTemplate_1.SIMPLE_BLANK_TABLE_TEMPLATE;
|
|
145
|
+
(0, globals_1.expect)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
146
|
+
return __generator(this, function (_a) {
|
|
147
|
+
switch (_a.label) {
|
|
148
|
+
case 0: return [4 /*yield*/, jszip_1.default.loadAsync(singleTableDefaultTemplate, {
|
|
149
|
+
base64: true,
|
|
150
|
+
})];
|
|
151
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}); }).not.toThrow();
|
|
155
|
+
return [4 /*yield*/, jszip_1.default.loadAsync(singleTableDefaultTemplate, {
|
|
156
|
+
base64: true,
|
|
157
|
+
})];
|
|
158
|
+
case 1:
|
|
159
|
+
defaultZipFile = _c.sent();
|
|
160
|
+
data = [
|
|
161
|
+
["ID", "Name", "Income", "Gross", "Bonus"],
|
|
162
|
+
[123, "Alan C", 155000, 155000, 0.15],
|
|
163
|
+
[331, "Tim C", 65000, 13000, 0.12],
|
|
164
|
+
[222, "Bill G", 29501, 8850.3, 0.18],
|
|
165
|
+
[5582, "Mitch M", 87960, 17592, 0.15],
|
|
166
|
+
[43, "Dan F", 197296, 19729.6, 0.22],
|
|
167
|
+
[22, "Perry T-P", 186006, 37201.2, 0.4],
|
|
168
|
+
[335, "Mdrake", 197136, 78854.4, 0.1],
|
|
169
|
+
[6590, "Dr P", 139636, 41890.8, 0.13],
|
|
170
|
+
];
|
|
171
|
+
tableData = utils_1.gridUtils.parseToTableData({ data: data, config: { promoteHeaders: true, adjustColumnNames: true } });
|
|
172
|
+
return [4 /*yield*/, utils_1.xmlPartsUtils.updateWorkbookDataAndConfigurations(defaultZipFile, undefined, tableData)];
|
|
173
|
+
case 2:
|
|
174
|
+
_c.sent();
|
|
175
|
+
_a = globals_1.expect;
|
|
176
|
+
return [4 /*yield*/, ((_b = defaultZipFile.file("xl/tables/table1.xml")) === null || _b === void 0 ? void 0 : _b.async("text"))];
|
|
177
|
+
case 3:
|
|
178
|
+
_a.apply(void 0, [_c.sent()]).toContain("A1:E9");
|
|
179
|
+
return [2 /*return*/];
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}); });
|
|
183
|
+
(0, globals_1.test)("Table XML contains correct Table reference value without headers included", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
184
|
+
var singleTableDefaultTemplate, defaultZipFile, data, tableData, _a;
|
|
185
|
+
var _b;
|
|
186
|
+
return __generator(this, function (_c) {
|
|
187
|
+
switch (_c.label) {
|
|
188
|
+
case 0:
|
|
189
|
+
singleTableDefaultTemplate = workbookTemplate_1.SIMPLE_BLANK_TABLE_TEMPLATE;
|
|
190
|
+
(0, globals_1.expect)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
191
|
+
return __generator(this, function (_a) {
|
|
192
|
+
switch (_a.label) {
|
|
193
|
+
case 0: return [4 /*yield*/, jszip_1.default.loadAsync(singleTableDefaultTemplate, {
|
|
194
|
+
base64: true,
|
|
195
|
+
})];
|
|
196
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}); }).not.toThrow();
|
|
200
|
+
return [4 /*yield*/, jszip_1.default.loadAsync(singleTableDefaultTemplate, {
|
|
201
|
+
base64: true,
|
|
202
|
+
})];
|
|
203
|
+
case 1:
|
|
204
|
+
defaultZipFile = _c.sent();
|
|
205
|
+
data = [
|
|
206
|
+
["ID", "Name", "Income", "Gross", "Bonus"],
|
|
207
|
+
[123, "Alan C", 155000, 155000, 0.15],
|
|
208
|
+
[331, "Tim C", 65000, 13000, 0.12],
|
|
209
|
+
[222, "Bill G", 29501, 8850.3, 0.18],
|
|
210
|
+
[5582, "Mitch M", 87960, 17592, 0.15],
|
|
211
|
+
[43, "Dan F", 197296, 19729.6, 0.22],
|
|
212
|
+
[22, "Perry T-P", 186006, 37201.2, 0.4],
|
|
213
|
+
[335, "Mdrake", 197136, 78854.4, 0.1],
|
|
214
|
+
[6590, "Dr P", 139636, 41890.8, 0.13],
|
|
215
|
+
];
|
|
216
|
+
tableData = utils_1.gridUtils.parseToTableData({ data: data, config: { promoteHeaders: false, adjustColumnNames: true } });
|
|
217
|
+
return [4 /*yield*/, utils_1.xmlPartsUtils.updateWorkbookDataAndConfigurations(defaultZipFile, undefined, tableData)];
|
|
218
|
+
case 2:
|
|
219
|
+
_c.sent();
|
|
220
|
+
_a = globals_1.expect;
|
|
221
|
+
return [4 /*yield*/, ((_b = defaultZipFile.file("xl/tables/table1.xml")) === null || _b === void 0 ? void 0 : _b.async("text"))];
|
|
222
|
+
case 3:
|
|
223
|
+
_a.apply(void 0, [_c.sent()]).toContain("A1:E10");
|
|
224
|
+
return [2 /*return*/];
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}); });
|
|
228
|
+
(0, globals_1.test)("Table XML contains correct Table reference value using template", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
229
|
+
var movedTableDefaultTemplate, templateMovedZipFile, data, tableData, _a;
|
|
230
|
+
var _b;
|
|
231
|
+
return __generator(this, function (_c) {
|
|
232
|
+
switch (_c.label) {
|
|
233
|
+
case 0:
|
|
234
|
+
movedTableDefaultTemplate = workbookTemplate_1.WORKBOOK_TEMPLATE_MOVED_TABLE;
|
|
235
|
+
(0, globals_1.expect)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
236
|
+
return __generator(this, function (_a) {
|
|
237
|
+
switch (_a.label) {
|
|
238
|
+
case 0: return [4 /*yield*/, jszip_1.default.loadAsync(movedTableDefaultTemplate, {
|
|
239
|
+
base64: true,
|
|
240
|
+
})];
|
|
241
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}); }).not.toThrow();
|
|
245
|
+
return [4 /*yield*/, jszip_1.default.loadAsync(movedTableDefaultTemplate, {
|
|
246
|
+
base64: true,
|
|
247
|
+
})];
|
|
248
|
+
case 1:
|
|
249
|
+
templateMovedZipFile = _c.sent();
|
|
250
|
+
data = [
|
|
251
|
+
["ID", "Name", "Income", "Gross", "Bonus"],
|
|
252
|
+
[123, "Alan C", 155000, 155000, 0.15],
|
|
253
|
+
[331, "Tim C", 65000, 13000, 0.12],
|
|
254
|
+
[222, "Bill G", 29501, 8850.3, 0.18],
|
|
255
|
+
[5582, "Mitch M", 87960, 17592, 0.15],
|
|
256
|
+
[43, "Dan F", 197296, 19729.6, 0.22],
|
|
257
|
+
[22, "Perry T-P", 186006, 37201.2, 0.4],
|
|
258
|
+
[335, "Mdrake", 197136, 78854.4, 0.1],
|
|
259
|
+
[6590, "Dr P", 139636, 41890.8, 0.13],
|
|
260
|
+
];
|
|
261
|
+
tableData = utils_1.gridUtils.parseToTableData({ data: data, config: { promoteHeaders: true, adjustColumnNames: true } });
|
|
262
|
+
return [4 /*yield*/, utils_1.xmlPartsUtils.updateWorkbookDataAndConfigurations(templateMovedZipFile, { templateFile: templateMovedZipFile }, tableData)];
|
|
263
|
+
case 2:
|
|
264
|
+
_c.sent();
|
|
265
|
+
_a = globals_1.expect;
|
|
266
|
+
return [4 /*yield*/, ((_b = templateMovedZipFile.file("xl/tables/table1.xml")) === null || _b === void 0 ? void 0 : _b.async("text"))];
|
|
267
|
+
case 3:
|
|
268
|
+
_a.apply(void 0, [_c.sent()]).toContain("B2:F10");
|
|
128
269
|
return [2 /*return*/];
|
|
129
270
|
}
|
|
130
271
|
});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
export interface QueryInfo {
|
|
2
3
|
refreshOnOpen: boolean;
|
|
3
4
|
queryMashup: string;
|
|
@@ -29,9 +30,14 @@ export interface GridConfig {
|
|
|
29
30
|
adjustColumnNames?: boolean;
|
|
30
31
|
}
|
|
31
32
|
export interface FileConfigs {
|
|
32
|
-
templateFile?: File;
|
|
33
|
+
templateFile?: File | Buffer;
|
|
33
34
|
docProps?: DocProps;
|
|
34
35
|
hostName?: string;
|
|
36
|
+
templateSettings?: TemplateSettings;
|
|
37
|
+
}
|
|
38
|
+
export interface TemplateSettings {
|
|
39
|
+
tableName?: string;
|
|
40
|
+
sheetName?: string;
|
|
35
41
|
}
|
|
36
42
|
export declare enum DataTypes {
|
|
37
43
|
null = 0,
|
package/dist/utils/constants.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright (c) Microsoft Corporation.
|
|
3
3
|
// Licensed under the MIT license.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.
|
|
6
|
-
exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = void 0;
|
|
5
|
+
exports.textResultType = exports.application = exports.uint8ArrayType = exports.blobFileType = exports.relationshipErr = exports.columnIndexOutOfRangeErr = exports.xlRelsNotFoundErr = exports.relsNotFoundErr = exports.arrayIsntMxNErr = exports.unexpectedErr = exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = exports.InvalidColumnNameErr = exports.stylesNotFoundErr = exports.EmptyQueryNameErr = exports.QueryNameInvalidCharsErr = exports.QueryNameMaxLengthErr = exports.invalidDataTypeErr = exports.headerNotFoundErr = exports.invalidValueInColumnErr = exports.tableReferenceNotFoundErr = exports.tableNotFoundErr = exports.queryTableNotFoundErr = exports.templateWithInitialDataErr = exports.formulaSectionNotFoundErr = exports.queryConnectionNotFoundErr = exports.queryAndPivotTableNotFoundErr = exports.queryNameNotFoundErr = exports.emptyQueryMashupErr = exports.base64NotFoundErr = exports.sheetsNotFoundErr = exports.WorkbookNotFoundERR = exports.connectionsNotFoundErr = exports.sharedStringsNotFoundErr = exports.docPropsAppXmlPath = exports.labelInfoXmlPath = exports.workbookRelsXmlPath = exports.docPropsRootElement = exports.docMetadataXmlPath = exports.relsXmlPath = exports.docPropsCoreXmlPath = exports.section1mPath = exports.pivotCachesPath = exports.tablesFolderPath = exports.queryTablesPath = exports.workbookXmlPath = exports.queryTableXmlPath = exports.tableXmlPath = exports.sheetsXmlPath = exports.sharedStringsXmlPath = exports.connectionsXmlPath = void 0;
|
|
6
|
+
exports.OFU = exports.headers = exports.URLS = exports.defaults = exports.elementAttributesValues = exports.dataTypeKind = exports.elementAttributes = exports.element = exports.BOM = exports.falseStr = exports.trueStr = exports.maxQueryLength = exports.divider = exports.section1PathPrefix = exports.emptyValue = exports.falseValue = exports.trueValue = exports.pivotCachesPathPrefix = exports.xmlTextResultType = void 0;
|
|
7
7
|
exports.connectionsXmlPath = "xl/connections.xml";
|
|
8
8
|
exports.sharedStringsXmlPath = "xl/sharedStrings.xml";
|
|
9
9
|
exports.sheetsXmlPath = "xl/worksheets/sheet1.xml";
|
|
@@ -11,14 +11,19 @@ exports.tableXmlPath = "xl/tables/table1.xml";
|
|
|
11
11
|
exports.queryTableXmlPath = "xl/queryTables/queryTable1.xml";
|
|
12
12
|
exports.workbookXmlPath = "xl/workbook.xml";
|
|
13
13
|
exports.queryTablesPath = "xl/queryTables/";
|
|
14
|
+
exports.tablesFolderPath = "xl/tables/";
|
|
14
15
|
exports.pivotCachesPath = "xl/pivotCache/";
|
|
15
16
|
exports.section1mPath = "Formulas/Section1.m";
|
|
16
17
|
exports.docPropsCoreXmlPath = "docProps/core.xml";
|
|
17
18
|
exports.relsXmlPath = "_rels/.rels";
|
|
18
19
|
exports.docMetadataXmlPath = "docMetadata";
|
|
19
20
|
exports.docPropsRootElement = "cp:coreProperties";
|
|
21
|
+
exports.workbookRelsXmlPath = "xl/_rels/workbook.xml.rels";
|
|
22
|
+
exports.labelInfoXmlPath = "docMetadata/LabelInfo.xml";
|
|
23
|
+
exports.docPropsAppXmlPath = "docProps/app.xml";
|
|
20
24
|
exports.sharedStringsNotFoundErr = "SharedStrings were not found in template";
|
|
21
25
|
exports.connectionsNotFoundErr = "Connections were not found in template";
|
|
26
|
+
exports.WorkbookNotFoundERR = "workbook was not found in template";
|
|
22
27
|
exports.sheetsNotFoundErr = "Sheets were not found in template";
|
|
23
28
|
exports.base64NotFoundErr = "Base64 was not found in template";
|
|
24
29
|
exports.emptyQueryMashupErr = "Query mashup is empty";
|
|
@@ -29,6 +34,7 @@ exports.formulaSectionNotFoundErr = "Formula section wasn't found in template";
|
|
|
29
34
|
exports.templateWithInitialDataErr = "Cannot use a template file with initial data";
|
|
30
35
|
exports.queryTableNotFoundErr = "Query table wasn't found in template";
|
|
31
36
|
exports.tableNotFoundErr = "Table wasn't found in template";
|
|
37
|
+
exports.tableReferenceNotFoundErr = "Reference not found in the table XML.";
|
|
32
38
|
exports.invalidValueInColumnErr = "Invalid cell value in column";
|
|
33
39
|
exports.headerNotFoundErr = "Invalid JSON file, header is missing";
|
|
34
40
|
exports.invalidDataTypeErr = "Invalid JSON file, invalid data type";
|
|
@@ -41,7 +47,9 @@ exports.promotedHeadersCannotBeUsedWithoutAdjustingColumnNamesErr = "Headers can
|
|
|
41
47
|
exports.unexpectedErr = "Unexpected error";
|
|
42
48
|
exports.arrayIsntMxNErr = "Array isn't MxN";
|
|
43
49
|
exports.relsNotFoundErr = ".rels were not found in template";
|
|
50
|
+
exports.xlRelsNotFoundErr = "workbook.xml.rels were not found xl";
|
|
44
51
|
exports.columnIndexOutOfRangeErr = "Column index out of range";
|
|
52
|
+
exports.relationshipErr = "Relationship not found";
|
|
45
53
|
exports.blobFileType = "blob";
|
|
46
54
|
exports.uint8ArrayType = "uint8array";
|
|
47
55
|
exports.application = "application/xlsx";
|
|
@@ -85,6 +93,9 @@ exports.element = {
|
|
|
85
93
|
dimension: "dimension",
|
|
86
94
|
selection: "selection",
|
|
87
95
|
kindCell: "c",
|
|
96
|
+
sheet: "sheet",
|
|
97
|
+
relationships: "Relationships",
|
|
98
|
+
relationship: "Relationship"
|
|
88
99
|
};
|
|
89
100
|
exports.elementAttributes = {
|
|
90
101
|
connection: "connection",
|
|
@@ -98,6 +109,11 @@ exports.elementAttributes = {
|
|
|
98
109
|
name: "name",
|
|
99
110
|
description: "description",
|
|
100
111
|
id: "id",
|
|
112
|
+
Id: "Id",
|
|
113
|
+
relationId: "r:id",
|
|
114
|
+
relationId1: "RId1",
|
|
115
|
+
relationId2: "RId2",
|
|
116
|
+
relationId3: "RId3",
|
|
101
117
|
type: "Type",
|
|
102
118
|
value: "Value",
|
|
103
119
|
relationshipInfo: "RelationshipInfoContainer",
|
|
@@ -117,6 +133,7 @@ exports.elementAttributes = {
|
|
|
117
133
|
x14acDyDescent: "x14ac:dyDescent",
|
|
118
134
|
xr3uid: "xr3:uid",
|
|
119
135
|
space: "xml:space",
|
|
136
|
+
target: "Target",
|
|
120
137
|
};
|
|
121
138
|
exports.dataTypeKind = {
|
|
122
139
|
string: "str",
|
|
@@ -134,6 +151,7 @@ exports.defaults = {
|
|
|
134
151
|
queryName: "Query1",
|
|
135
152
|
sheetName: "Sheet1",
|
|
136
153
|
columnName: "Column",
|
|
154
|
+
tableName: "Table1",
|
|
137
155
|
};
|
|
138
156
|
exports.URLS = {
|
|
139
157
|
PQ: [
|
|
@@ -93,13 +93,27 @@ var convertToExcelColumn = function (index) {
|
|
|
93
93
|
var base = 26; // number of letters in the alphabet
|
|
94
94
|
while (index >= 0) {
|
|
95
95
|
var remainder = index % base;
|
|
96
|
-
columnStr = String.fromCharCode(remainder +
|
|
96
|
+
columnStr = String.fromCharCode(remainder + 'A'.charCodeAt(0)) + columnStr;
|
|
97
97
|
index = Math.floor(index / base) - 1;
|
|
98
98
|
}
|
|
99
99
|
return columnStr;
|
|
100
100
|
};
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Parse an Excel range (e.g. "B2:D10") and return its starting row and column indices.
|
|
103
|
+
* @param cellRangeRef - Range reference string.
|
|
104
|
+
* @returns Object with numeric row and column.
|
|
105
|
+
*/
|
|
106
|
+
var GetStartPosition = function (cellRangeRef) {
|
|
107
|
+
var match = cellRangeRef.toUpperCase().match(/^([A-Z]+)(\d+)/);
|
|
108
|
+
if (!match) {
|
|
109
|
+
return { row: 0, column: 0 };
|
|
110
|
+
}
|
|
111
|
+
var colLetters = match[1], rowStr = match[2];
|
|
112
|
+
var row = parseInt(rowStr, 10);
|
|
113
|
+
var column = colLetters
|
|
114
|
+
.split("")
|
|
115
|
+
.reduce(function (acc, char) { return acc * 26 + (char.charCodeAt(0) - "A".charCodeAt(0) + 1); }, 0);
|
|
116
|
+
return { row: row, column: column };
|
|
103
117
|
};
|
|
104
118
|
var createCellElement = function (doc, colIndex, rowIndex, data) {
|
|
105
119
|
var cell = doc.createElementNS(doc.documentElement.namespaceURI, constants_1.element.kindCell);
|
|
@@ -146,8 +160,8 @@ exports.default = {
|
|
|
146
160
|
getCellReferenceRelative: getCellReferenceRelative,
|
|
147
161
|
getCellReferenceAbsolute: getCellReferenceAbsolute,
|
|
148
162
|
createCell: createCellElement,
|
|
149
|
-
getTableReference: getTableReference,
|
|
150
163
|
updateCellData: updateCellData,
|
|
151
164
|
resolveType: resolveType,
|
|
152
165
|
convertToExcelColumn: convertToExcelColumn,
|
|
166
|
+
GetStartPosition: GetStartPosition,
|
|
153
167
|
};
|
package/dist/utils/tableUtils.js
CHANGED
|
@@ -45,7 +45,17 @@ var constants_1 = require("./constants");
|
|
|
45
45
|
var documentUtils_1 = __importDefault(require("./documentUtils"));
|
|
46
46
|
var uuid_1 = require("uuid");
|
|
47
47
|
var xmldom_qsa_1 = require("xmldom-qsa");
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Update initial data for a table, its sheet, query table, and defined name if provided.
|
|
50
|
+
* @param zip - The JSZip instance containing workbook parts.
|
|
51
|
+
* @param cellRangeRef - Cell range reference (e.g. "A1:C5").
|
|
52
|
+
* @param sheetPath - Path to the sheet XML within the zip.
|
|
53
|
+
* @param tablePath - Path to the table XML within the zip.
|
|
54
|
+
* @param tableName - Name of the table.
|
|
55
|
+
* @param tableData - Optional TableData containing headers and rows.
|
|
56
|
+
* @param updateQueryTable - Whether to update the associated queryTable part.
|
|
57
|
+
*/
|
|
58
|
+
var updateTableInitialDataIfNeeded = function (zip, cellRangeRef, sheetPath, tablePath, sheetName, tableData, updateQueryTable) { return __awaiter(void 0, void 0, void 0, function () {
|
|
49
59
|
var sheetsXmlString, newSheet, queryTableXmlString, newQueryTable, workbookXmlString, newWorkbook, tableXmlString, newTable;
|
|
50
60
|
var _a, _b, _c, _d;
|
|
51
61
|
return __generator(this, function (_e) {
|
|
@@ -54,14 +64,14 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
|
|
|
54
64
|
if (!tableData) {
|
|
55
65
|
return [2 /*return*/];
|
|
56
66
|
}
|
|
57
|
-
return [4 /*yield*/, ((_a = zip.file(
|
|
67
|
+
return [4 /*yield*/, ((_a = zip.file(sheetPath)) === null || _a === void 0 ? void 0 : _a.async(constants_1.textResultType))];
|
|
58
68
|
case 1:
|
|
59
69
|
sheetsXmlString = _e.sent();
|
|
60
70
|
if (sheetsXmlString === undefined) {
|
|
61
71
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
62
72
|
}
|
|
63
|
-
newSheet = updateSheetsInitialData(sheetsXmlString, tableData);
|
|
64
|
-
zip.file(
|
|
73
|
+
newSheet = updateSheetsInitialData(sheetsXmlString, tableData, cellRangeRef);
|
|
74
|
+
zip.file(sheetPath, newSheet);
|
|
65
75
|
if (!updateQueryTable) return [3 /*break*/, 5];
|
|
66
76
|
return [4 /*yield*/, ((_b = zip.file(constants_1.queryTableXmlPath)) === null || _b === void 0 ? void 0 : _b.async(constants_1.textResultType))];
|
|
67
77
|
case 2:
|
|
@@ -79,22 +89,30 @@ var updateTableInitialDataIfNeeded = function (zip, tableData, updateQueryTable)
|
|
|
79
89
|
if (workbookXmlString === undefined) {
|
|
80
90
|
throw new Error(constants_1.sheetsNotFoundErr);
|
|
81
91
|
}
|
|
82
|
-
newWorkbook = updateWorkbookInitialData(workbookXmlString,
|
|
92
|
+
newWorkbook = updateWorkbookInitialData(workbookXmlString, sheetName + GenerateReferenceFromString(cellRangeRef));
|
|
83
93
|
zip.file(constants_1.workbookXmlPath, newWorkbook);
|
|
84
94
|
_e.label = 5;
|
|
85
|
-
case 5: return [4 /*yield*/, ((_d = zip.file(
|
|
95
|
+
case 5: return [4 /*yield*/, ((_d = zip.file(tablePath)) === null || _d === void 0 ? void 0 : _d.async(constants_1.textResultType))];
|
|
86
96
|
case 6:
|
|
87
97
|
tableXmlString = _e.sent();
|
|
88
98
|
if (tableXmlString === undefined) {
|
|
89
99
|
throw new Error(constants_1.tableNotFoundErr);
|
|
90
100
|
}
|
|
91
|
-
newTable = updateTablesInitialData(tableXmlString, tableData, updateQueryTable);
|
|
92
|
-
zip.file(
|
|
101
|
+
newTable = updateTablesInitialData(tableXmlString, tableData, cellRangeRef, updateQueryTable);
|
|
102
|
+
zip.file(tablePath, newTable);
|
|
93
103
|
return [2 /*return*/];
|
|
94
104
|
}
|
|
95
105
|
});
|
|
96
106
|
}); };
|
|
97
|
-
|
|
107
|
+
/**
|
|
108
|
+
* Generate updated table XML string with new columns, reference, and filter range.
|
|
109
|
+
* @param tableXmlString - Original table XML.
|
|
110
|
+
* @param tableData - TableData containing column names.
|
|
111
|
+
* @param cellRangeRef - Cell range reference.
|
|
112
|
+
* @param updateQueryTable - Whether to include queryTable attributes.
|
|
113
|
+
* @returns Serialized XML string of the updated table.
|
|
114
|
+
*/
|
|
115
|
+
var updateTablesInitialData = function (tableXmlString, tableData, cellRangeRef, updateQueryTable) {
|
|
98
116
|
if (updateQueryTable === void 0) { updateQueryTable = false; }
|
|
99
117
|
var parser = new xmldom_qsa_1.DOMParser();
|
|
100
118
|
var serializer = new xmldom_qsa_1.XMLSerializer();
|
|
@@ -115,19 +133,24 @@ var updateTablesInitialData = function (tableXmlString, tableData, updateQueryTa
|
|
|
115
133
|
tableColumns.setAttribute(constants_1.elementAttributes.count, tableData.columnNames.length.toString());
|
|
116
134
|
tableDoc
|
|
117
135
|
.getElementsByTagName(constants_1.element.table)[0]
|
|
118
|
-
.setAttribute(constants_1.elementAttributes.reference,
|
|
136
|
+
.setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
119
137
|
tableDoc
|
|
120
138
|
.getElementsByTagName(constants_1.element.autoFilter)[0]
|
|
121
|
-
.setAttribute(constants_1.elementAttributes.reference,
|
|
139
|
+
.setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
122
140
|
return serializer.serializeToString(tableDoc);
|
|
123
141
|
};
|
|
124
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Update the definedName element in workbook XML to a custom name.
|
|
144
|
+
* @param workbookXmlString - Original workbook XML string.
|
|
145
|
+
* @param customDefinedName - New defined name text content (e.g. "!$A$1:$C$5").
|
|
146
|
+
* @returns Serialized XML string of the updated workbook.
|
|
147
|
+
*/
|
|
148
|
+
var updateWorkbookInitialData = function (workbookXmlString, customDefinedName) {
|
|
125
149
|
var newParser = new xmldom_qsa_1.DOMParser();
|
|
126
150
|
var newSerializer = new xmldom_qsa_1.XMLSerializer();
|
|
127
151
|
var workbookDoc = newParser.parseFromString(workbookXmlString, constants_1.xmlTextResultType);
|
|
128
152
|
var definedName = workbookDoc.getElementsByTagName(constants_1.element.definedName)[0];
|
|
129
|
-
definedName.textContent =
|
|
130
|
-
constants_1.defaults.sheetName + "!$A$1:".concat(documentUtils_1.default.getCellReferenceAbsolute(tableData.columnNames.length - 1, tableData.rows.length + 1));
|
|
153
|
+
definedName.textContent = customDefinedName;
|
|
131
154
|
return newSerializer.serializeToString(workbookDoc);
|
|
132
155
|
};
|
|
133
156
|
var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
|
|
@@ -147,42 +170,64 @@ var updateQueryTablesInitialData = function (queryTableXmlString, tableData) {
|
|
|
147
170
|
queryTableDoc.getElementsByTagName(constants_1.element.queryTableRefresh)[0].setAttribute(constants_1.elementAttributes.nextId, (tableData.columnNames.length + 1).toString());
|
|
148
171
|
return serializer.serializeToString(queryTableDoc);
|
|
149
172
|
};
|
|
150
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Update sheet XML with header row and data rows based on TableData.
|
|
175
|
+
* @param sheetsXmlString - Original sheet XML string.
|
|
176
|
+
* @param tableData - TableData containing headers and rows.
|
|
177
|
+
* @param cellRangeRef - Cell range reference.
|
|
178
|
+
* @returns Serialized XML string of the updated sheet.
|
|
179
|
+
*/
|
|
180
|
+
var updateSheetsInitialData = function (sheetsXmlString, tableData, cellRangeRef) {
|
|
181
|
+
var _a = documentUtils_1.default.GetStartPosition(cellRangeRef), row = _a.row, column = _a.column;
|
|
151
182
|
var parser = new xmldom_qsa_1.DOMParser();
|
|
152
183
|
var serializer = new xmldom_qsa_1.XMLSerializer();
|
|
153
184
|
var sheetsDoc = parser.parseFromString(sheetsXmlString, constants_1.xmlTextResultType);
|
|
154
185
|
var sheetData = sheetsDoc.getElementsByTagName(constants_1.element.sheetData)[0];
|
|
155
186
|
sheetData.textContent = "";
|
|
156
|
-
var rowIndex = 0;
|
|
157
187
|
var columnRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
|
|
158
|
-
columnRow.setAttribute(constants_1.elementAttributes.row,
|
|
159
|
-
columnRow.setAttribute(constants_1.elementAttributes.spans, "
|
|
188
|
+
columnRow.setAttribute(constants_1.elementAttributes.row, row.toString());
|
|
189
|
+
columnRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
|
|
160
190
|
columnRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
|
|
161
191
|
tableData.columnNames.forEach(function (col, colIndex) {
|
|
162
|
-
columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex,
|
|
192
|
+
columnRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, col));
|
|
163
193
|
});
|
|
164
194
|
sheetData.appendChild(columnRow);
|
|
165
|
-
|
|
166
|
-
tableData.rows.forEach(function (
|
|
195
|
+
row++;
|
|
196
|
+
tableData.rows.forEach(function (_row) {
|
|
167
197
|
var newRow = sheetsDoc.createElementNS(sheetsDoc.documentElement.namespaceURI, constants_1.element.row);
|
|
168
|
-
newRow.setAttribute(constants_1.elementAttributes.row,
|
|
169
|
-
newRow.setAttribute(constants_1.elementAttributes.spans, "
|
|
198
|
+
newRow.setAttribute(constants_1.elementAttributes.row, row.toString());
|
|
199
|
+
newRow.setAttribute(constants_1.elementAttributes.spans, column + ":" + (column + tableData.columnNames.length - 1));
|
|
170
200
|
newRow.setAttribute(constants_1.elementAttributes.x14acDyDescent, "0.3");
|
|
171
|
-
|
|
172
|
-
newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex,
|
|
201
|
+
_row.forEach(function (cellContent, colIndex) {
|
|
202
|
+
newRow.appendChild(documentUtils_1.default.createCell(sheetsDoc, colIndex + column - 1, row - 1, cellContent));
|
|
173
203
|
});
|
|
174
204
|
sheetData.appendChild(newRow);
|
|
175
|
-
|
|
205
|
+
row++;
|
|
176
206
|
});
|
|
177
|
-
|
|
178
|
-
sheetsDoc.getElementsByTagName(constants_1.element.
|
|
179
|
-
sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, reference);
|
|
207
|
+
sheetsDoc.getElementsByTagName(constants_1.element.dimension)[0].setAttribute(constants_1.elementAttributes.reference, cellRangeRef);
|
|
208
|
+
sheetsDoc.getElementsByTagName(constants_1.element.selection)[0].setAttribute(constants_1.elementAttributes.sqref, cellRangeRef);
|
|
180
209
|
return serializer.serializeToString(sheetsDoc);
|
|
181
210
|
};
|
|
211
|
+
/**
|
|
212
|
+
* Add Excel-style dollar signs and a '!' prefix to a cell range.
|
|
213
|
+
* Converts "A1:B2" into "!$A$1:$B$2".
|
|
214
|
+
* @param cellRangeRef - Range reference string without dollar signs.
|
|
215
|
+
* @returns Range with dollar signs and prefix.
|
|
216
|
+
*/
|
|
217
|
+
var GenerateReferenceFromString = function (cellRangeRef) {
|
|
218
|
+
return "!" + cellRangeRef.split(":").map(function (part) {
|
|
219
|
+
var match = part.match(/^([A-Za-z]+)(\d+)$/);
|
|
220
|
+
if (match) {
|
|
221
|
+
var col = match[1], row = match[2];
|
|
222
|
+
return "$".concat(col.toUpperCase(), "$").concat(row);
|
|
223
|
+
}
|
|
224
|
+
}).join(":");
|
|
225
|
+
};
|
|
182
226
|
exports.default = {
|
|
183
227
|
updateTableInitialDataIfNeeded: updateTableInitialDataIfNeeded,
|
|
184
228
|
updateSheetsInitialData: updateSheetsInitialData,
|
|
185
229
|
updateWorkbookInitialData: updateWorkbookInitialData,
|
|
186
230
|
updateTablesInitialData: updateTablesInitialData,
|
|
187
231
|
updateQueryTablesInitialData: updateQueryTablesInitialData,
|
|
232
|
+
GenerateReferenceFromString: GenerateReferenceFromString,
|
|
188
233
|
};
|