@8ms/helpers 3.2.5 → 3.2.7
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/dist/aws/s3/server/AwsS3.cjs +1 -0
- package/dist/aws/s3/server/AwsS3.mjs +1 -0
- package/dist/googleAds/keywordPlanner/_shared/index.cjs +2 -1
- package/dist/googleAds/keywordPlanner/_shared/index.d.cts +2 -2
- package/dist/googleAds/keywordPlanner/_shared/index.d.mts +2 -2
- package/dist/googleAds/keywordPlanner/_shared/index.mjs +2 -2
- package/dist/googleAds/keywordPlanner/_shared/network.cjs +18 -8
- package/dist/googleAds/keywordPlanner/_shared/network.d.cts +12 -6
- package/dist/googleAds/keywordPlanner/_shared/network.d.mts +12 -6
- package/dist/googleAds/keywordPlanner/_shared/network.mjs +17 -8
- package/dist/googleAds/keywordPlanner/client/index.cjs +2 -1
- package/dist/googleAds/keywordPlanner/client/index.d.cts +2 -2
- package/dist/googleAds/keywordPlanner/client/index.d.mts +2 -2
- package/dist/googleAds/keywordPlanner/client/index.mjs +2 -2
- package/dist/googleAds/keywordPlanner/server/index.cjs +2 -3
- package/dist/googleAds/keywordPlanner/server/index.d.cts +2 -3
- package/dist/googleAds/keywordPlanner/server/index.d.mts +2 -3
- package/dist/googleAds/keywordPlanner/server/index.mjs +2 -3
- package/dist/googleCloud/bigquery/_shared/field/bqFieldMode.cjs +2 -1
- package/dist/googleCloud/bigquery/_shared/field/bqFieldMode.d.cts +2 -0
- package/dist/googleCloud/bigquery/_shared/field/bqFieldMode.d.mts +2 -0
- package/dist/googleCloud/bigquery/_shared/field/bqFieldMode.mjs +2 -1
- package/dist/googleCloud/bigquery/_shared/zodToBQDefinition.cjs +3 -2
- package/dist/googleCloud/bigquery/_shared/zodToBQDefinition.d.cts +1 -1
- package/dist/googleCloud/bigquery/_shared/zodToBQDefinition.d.mts +1 -1
- package/dist/googleCloud/bigquery/_shared/zodToBQDefinition.mjs +3 -2
- package/dist/googleCloud/drive/server/GoogleCloudDrive.cjs +1 -0
- package/dist/googleCloud/drive/server/GoogleCloudDrive.mjs +1 -0
- package/dist/util/server/buildId.cjs +13 -0
- package/dist/util/server/buildId.d.cts +7 -0
- package/dist/util/server/buildId.d.mts +7 -0
- package/dist/util/server/buildId.mjs +12 -0
- package/dist/util/server/index.cjs +2 -0
- package/dist/util/server/index.d.cts +2 -1
- package/dist/util/server/index.d.mts +2 -1
- package/dist/util/server/index.mjs +2 -1
- package/dist/xlsx/_shared/createXlsx.cjs +12 -22
- package/dist/xlsx/_shared/createXlsx.mjs +12 -22
- package/dist/xlsx/_shared/modifyXlsx.cjs +32 -44
- package/dist/xlsx/_shared/modifyXlsx.mjs +32 -44
- package/dist/xlsx/client/index.cjs +0 -1
- package/dist/xlsx/client/index.mjs +0 -1
- package/dist/xlsx/server/index.cjs +0 -1
- package/dist/xlsx/server/index.mjs +0 -1
- package/dist/zip/_shared/ZipArchive.cjs +49 -0
- package/dist/zip/_shared/ZipArchive.d.cts +24 -0
- package/dist/zip/_shared/ZipArchive.d.mts +24 -0
- package/dist/zip/_shared/ZipArchive.mjs +48 -0
- package/dist/zip/_shared/crc32.cjs +24 -0
- package/dist/zip/_shared/crc32.d.cts +4 -0
- package/dist/zip/_shared/crc32.d.mts +4 -0
- package/dist/zip/_shared/crc32.mjs +23 -0
- package/dist/zip/_shared/deflate.cjs +21 -0
- package/dist/zip/_shared/deflate.d.cts +10 -0
- package/dist/zip/_shared/deflate.d.mts +10 -0
- package/dist/zip/_shared/deflate.mjs +19 -0
- package/dist/zip/_shared/index.cjs +12 -0
- package/dist/zip/_shared/index.d.cts +6 -0
- package/dist/zip/_shared/index.d.mts +6 -0
- package/dist/zip/_shared/index.mjs +6 -0
- package/dist/zip/_shared/readZip.cjs +63 -0
- package/dist/zip/_shared/readZip.d.cts +9 -0
- package/dist/zip/_shared/readZip.d.mts +9 -0
- package/dist/zip/_shared/readZip.mjs +62 -0
- package/dist/zip/_shared/writeZip.cjs +105 -0
- package/dist/zip/_shared/writeZip.d.cts +7 -0
- package/dist/zip/_shared/writeZip.d.mts +7 -0
- package/dist/zip/_shared/writeZip.mjs +104 -0
- package/dist/zip/client/index.cjs +12 -0
- package/dist/zip/client/index.d.cts +6 -0
- package/dist/zip/client/index.d.mts +6 -0
- package/dist/zip/client/index.mjs +6 -0
- package/dist/zip/server/index.cjs +12 -0
- package/dist/zip/server/index.d.cts +6 -0
- package/dist/zip/server/index.d.mts +6 -0
- package/dist/zip/server/index.mjs +6 -0
- package/package.json +37 -10
- package/dist/googleAds/keywordPlanner/server/buildRowId.cjs +0 -14
- package/dist/googleAds/keywordPlanner/server/buildRowId.d.cts +0 -8
- package/dist/googleAds/keywordPlanner/server/buildRowId.d.mts +0 -8
- package/dist/googleAds/keywordPlanner/server/buildRowId.mjs +0 -13
|
@@ -4,8 +4,9 @@ import { isUndefined } from "../_shared/isUndefined.mjs";
|
|
|
4
4
|
import { promiseChunks } from "../_shared/promiseChunks.mjs";
|
|
5
5
|
import { sleep } from "../_shared/sleep.mjs";
|
|
6
6
|
import { Sort, sort } from "../_shared/sort.mjs";
|
|
7
|
+
import { buildId } from "./buildId.mjs";
|
|
7
8
|
import { getBrotliCompressed } from "./getBrotliCompressed.mjs";
|
|
8
9
|
import { getBrotliDecompressed } from "./getBrotliDecompressed.mjs";
|
|
9
10
|
import { getGzipCompressed } from "./getGzipCompressed.mjs";
|
|
10
11
|
import { getGzipDecompressed } from "./getGzipDecompressed.mjs";
|
|
11
|
-
export { Sort, defaultTo, getBrotliCompressed, getBrotliDecompressed, getError, getGzipCompressed, getGzipDecompressed, isUndefined, promiseChunks, sleep, sort };
|
|
12
|
+
export { Sort, buildId, defaultTo, getBrotliCompressed, getBrotliDecompressed, getError, getGzipCompressed, getGzipDecompressed, isUndefined, promiseChunks, sleep, sort };
|
|
@@ -6,6 +6,7 @@ import { isUndefined } from "../_shared/isUndefined.mjs";
|
|
|
6
6
|
import { sleep } from "../_shared/sleep.mjs";
|
|
7
7
|
import { promiseChunks } from "../_shared/promiseChunks.mjs";
|
|
8
8
|
import { sort } from "../_shared/sort.mjs";
|
|
9
|
+
import { buildId } from "./buildId.mjs";
|
|
9
10
|
import { getBrotliCompressed } from "./getBrotliCompressed.mjs";
|
|
10
11
|
import { getGzipCompressed } from "./getGzipCompressed.mjs";
|
|
11
|
-
export { defaultTo, getBrotliCompressed, getBrotliDecompressed, getError, getGzipCompressed, getGzipDecompressed, isUndefined, promiseChunks, sleep, sort };
|
|
12
|
+
export { buildId, defaultTo, getBrotliCompressed, getBrotliDecompressed, getError, getGzipCompressed, getGzipDecompressed, isUndefined, promiseChunks, sleep, sort };
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_xlsx__shared_column = require("./column.cjs");
|
|
3
3
|
const require_xlsx__shared_cell = require("./cell.cjs");
|
|
4
|
+
const require_zip__shared_ZipArchive = require("../../zip/_shared/ZipArchive.cjs");
|
|
4
5
|
const require_xlsx__shared_sheet = require("./sheet.cjs");
|
|
5
6
|
//#region src/xlsx/_shared/createXlsx.ts
|
|
6
7
|
/**
|
|
7
|
-
* Builds a complete .xlsx workbook from scratch, using
|
|
8
|
-
*
|
|
8
|
+
* Builds a complete .xlsx workbook from scratch, using hand-written OOXML rather
|
|
9
|
+
* than a spreadsheet library.
|
|
9
10
|
*
|
|
10
11
|
* Nothing here touches `fs`, so it runs in the browser as happily as on the
|
|
11
12
|
* server — a page can turn data it has already loaded straight into a download.
|
|
12
|
-
*
|
|
13
|
-
* jszip is an optional peer dependency imported dynamically, so consumers that
|
|
14
|
-
* never build a workbook neither install it nor pay for it in their bundle.
|
|
15
13
|
*/
|
|
16
14
|
/** Style index of the bold row within the cellXfs list built by buildStylesXml. */
|
|
17
15
|
const HEADER_STYLE_INDEX = 1;
|
|
@@ -95,16 +93,15 @@ const buildPackageRelsXml = () => {
|
|
|
95
93
|
*/
|
|
96
94
|
const buildWorkbook = async (sheets) => {
|
|
97
95
|
if (0 === sheets.length) throw new Error("createXlsx requires at least one sheet.");
|
|
98
|
-
const
|
|
99
|
-
const zip = new JSZip();
|
|
96
|
+
const zip = new require_zip__shared_ZipArchive.ZipArchive();
|
|
100
97
|
const names = require_xlsx__shared_sheet.getUniqueSheetNames(sheets);
|
|
101
|
-
zip.
|
|
102
|
-
zip.
|
|
103
|
-
zip.
|
|
104
|
-
zip.
|
|
105
|
-
zip.
|
|
98
|
+
zip.set("[Content_Types].xml", buildContentTypesXml(sheets.length));
|
|
99
|
+
zip.set("_rels/.rels", buildPackageRelsXml());
|
|
100
|
+
zip.set("xl/workbook.xml", buildWorkbookXml(names));
|
|
101
|
+
zip.set("xl/_rels/workbook.xml.rels", buildWorkbookRelsXml(sheets.length));
|
|
102
|
+
zip.set("xl/styles.xml", buildStylesXml());
|
|
106
103
|
sheets.forEach((sheet, index) => {
|
|
107
|
-
zip.
|
|
104
|
+
zip.set(`xl/worksheets/sheet${index + 1}.xml`, buildWorksheetXml(sheet));
|
|
108
105
|
});
|
|
109
106
|
return zip;
|
|
110
107
|
};
|
|
@@ -117,21 +114,14 @@ const buildWorkbook = async (sheets) => {
|
|
|
117
114
|
* matter and a missing key becomes an empty cell.
|
|
118
115
|
*/
|
|
119
116
|
const createXlsx = async (sheets) => {
|
|
120
|
-
return (await buildWorkbook(sheets)).
|
|
121
|
-
type: "blob",
|
|
122
|
-
compression: "DEFLATE",
|
|
123
|
-
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
124
|
-
});
|
|
117
|
+
return (await buildWorkbook(sheets)).toBlob("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
125
118
|
};
|
|
126
119
|
/**
|
|
127
120
|
* As createXlsx, but returns raw bytes instead of a Blob — for server-side
|
|
128
121
|
* callers that need to stream or write the workbook rather than download it.
|
|
129
122
|
*/
|
|
130
123
|
const createXlsxBytes = async (sheets) => {
|
|
131
|
-
return (await buildWorkbook(sheets)).
|
|
132
|
-
type: "uint8array",
|
|
133
|
-
compression: "DEFLATE"
|
|
134
|
-
});
|
|
124
|
+
return (await buildWorkbook(sheets)).toBytes();
|
|
135
125
|
};
|
|
136
126
|
//#endregion
|
|
137
127
|
exports.createXlsx = createXlsx;
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { getColumLetter, getColumnWidth } from "./column.mjs";
|
|
2
2
|
import { buildCellXml, getCellValue, getEscapedXml } from "./cell.mjs";
|
|
3
|
+
import { ZipArchive } from "../../zip/_shared/ZipArchive.mjs";
|
|
3
4
|
import { getUniqueSheetNames } from "./sheet.mjs";
|
|
4
5
|
//#region src/xlsx/_shared/createXlsx.ts
|
|
5
6
|
/**
|
|
6
|
-
* Builds a complete .xlsx workbook from scratch, using
|
|
7
|
-
*
|
|
7
|
+
* Builds a complete .xlsx workbook from scratch, using hand-written OOXML rather
|
|
8
|
+
* than a spreadsheet library.
|
|
8
9
|
*
|
|
9
10
|
* Nothing here touches `fs`, so it runs in the browser as happily as on the
|
|
10
11
|
* server — a page can turn data it has already loaded straight into a download.
|
|
11
|
-
*
|
|
12
|
-
* jszip is an optional peer dependency imported dynamically, so consumers that
|
|
13
|
-
* never build a workbook neither install it nor pay for it in their bundle.
|
|
14
12
|
*/
|
|
15
13
|
/** Style index of the bold row within the cellXfs list built by buildStylesXml. */
|
|
16
14
|
const HEADER_STYLE_INDEX = 1;
|
|
@@ -94,16 +92,15 @@ const buildPackageRelsXml = () => {
|
|
|
94
92
|
*/
|
|
95
93
|
const buildWorkbook = async (sheets) => {
|
|
96
94
|
if (0 === sheets.length) throw new Error("createXlsx requires at least one sheet.");
|
|
97
|
-
const
|
|
98
|
-
const zip = new JSZip();
|
|
95
|
+
const zip = new ZipArchive();
|
|
99
96
|
const names = getUniqueSheetNames(sheets);
|
|
100
|
-
zip.
|
|
101
|
-
zip.
|
|
102
|
-
zip.
|
|
103
|
-
zip.
|
|
104
|
-
zip.
|
|
97
|
+
zip.set("[Content_Types].xml", buildContentTypesXml(sheets.length));
|
|
98
|
+
zip.set("_rels/.rels", buildPackageRelsXml());
|
|
99
|
+
zip.set("xl/workbook.xml", buildWorkbookXml(names));
|
|
100
|
+
zip.set("xl/_rels/workbook.xml.rels", buildWorkbookRelsXml(sheets.length));
|
|
101
|
+
zip.set("xl/styles.xml", buildStylesXml());
|
|
105
102
|
sheets.forEach((sheet, index) => {
|
|
106
|
-
zip.
|
|
103
|
+
zip.set(`xl/worksheets/sheet${index + 1}.xml`, buildWorksheetXml(sheet));
|
|
107
104
|
});
|
|
108
105
|
return zip;
|
|
109
106
|
};
|
|
@@ -116,21 +113,14 @@ const buildWorkbook = async (sheets) => {
|
|
|
116
113
|
* matter and a missing key becomes an empty cell.
|
|
117
114
|
*/
|
|
118
115
|
const createXlsx = async (sheets) => {
|
|
119
|
-
return (await buildWorkbook(sheets)).
|
|
120
|
-
type: "blob",
|
|
121
|
-
compression: "DEFLATE",
|
|
122
|
-
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
123
|
-
});
|
|
116
|
+
return (await buildWorkbook(sheets)).toBlob("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
124
117
|
};
|
|
125
118
|
/**
|
|
126
119
|
* As createXlsx, but returns raw bytes instead of a Blob — for server-side
|
|
127
120
|
* callers that need to stream or write the workbook rather than download it.
|
|
128
121
|
*/
|
|
129
122
|
const createXlsxBytes = async (sheets) => {
|
|
130
|
-
return (await buildWorkbook(sheets)).
|
|
131
|
-
type: "uint8array",
|
|
132
|
-
compression: "DEFLATE"
|
|
133
|
-
});
|
|
123
|
+
return (await buildWorkbook(sheets)).toBytes();
|
|
134
124
|
};
|
|
135
125
|
//#endregion
|
|
136
126
|
export { createXlsx, createXlsxBytes };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_xlsx__shared_cell = require("./cell.cjs");
|
|
3
|
+
const require_zip__shared_ZipArchive = require("../../zip/_shared/ZipArchive.cjs");
|
|
3
4
|
//#region src/xlsx/_shared/modifyXlsx.ts
|
|
4
5
|
/**
|
|
5
6
|
* Patches an existing .xlsx template: apply per-sheet XML transformations, add
|
|
@@ -46,80 +47,67 @@ const buildDrawingXml = (widthEmu, heightEmu) => {
|
|
|
46
47
|
* @param logo Optional PNG bytes, embedded into sheets with `addLogo`.
|
|
47
48
|
*/
|
|
48
49
|
const modifyXlsx = async (template, sheets, logo) => {
|
|
49
|
-
const zip = await
|
|
50
|
+
const zip = await require_zip__shared_ZipArchive.ZipArchive.load(template);
|
|
50
51
|
if (logo) {
|
|
51
|
-
zip.
|
|
52
|
-
|
|
53
|
-
if (
|
|
54
|
-
let contentTypesXml = await contentTypesFile.async("string");
|
|
52
|
+
zip.set("xl/media/image1.png", logo);
|
|
53
|
+
let contentTypesXml = zip.getText("[Content_Types].xml");
|
|
54
|
+
if (null !== contentTypesXml) {
|
|
55
55
|
if (!contentTypesXml.includes(`Extension="png"`)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
56
56
|
return `<Default Extension="png" ContentType="image/png"/></Types>`;
|
|
57
57
|
});
|
|
58
|
-
zip.
|
|
58
|
+
zip.set("[Content_Types].xml", contentTypesXml);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
let drawingCounter = 0;
|
|
62
62
|
for (const sheet of sheets) {
|
|
63
63
|
const filename = `xl/worksheets/sheet${sheet.index}.xml`;
|
|
64
|
-
let existing = zip.
|
|
65
|
-
if (
|
|
64
|
+
let existing = zip.getText(filename);
|
|
65
|
+
if (null === existing && sheet.createIfMissing) {
|
|
66
66
|
const name = sheet.sheetName ?? `Sheet${sheet.index}`;
|
|
67
67
|
const rId = `rId${sheet.index + 10}`;
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
zip.file("xl/_rels/workbook.xml.rels", relsXml.replace("</Relationships>", () => {
|
|
79
|
-
return `<Relationship Id="${rId}" Type="${WORKSHEET_REL_TYPE}" Target="worksheets/sheet${sheet.index}.xml"/></Relationships>`;
|
|
80
|
-
}));
|
|
81
|
-
}
|
|
82
|
-
zip.file(filename, EMPTY_SHEET_XML);
|
|
83
|
-
existing = zip.file(filename);
|
|
68
|
+
const workbookXml = zip.getText("xl/workbook.xml");
|
|
69
|
+
if (null !== workbookXml) zip.set("xl/workbook.xml", workbookXml.replace("</sheets>", () => {
|
|
70
|
+
return `<sheet name="${require_xlsx__shared_cell.getEscapedXml(name)}" sheetId="${sheet.index}" r:id="${rId}"/></sheets>`;
|
|
71
|
+
}));
|
|
72
|
+
const relsXml = zip.getText("xl/_rels/workbook.xml.rels");
|
|
73
|
+
if (null !== relsXml) zip.set("xl/_rels/workbook.xml.rels", relsXml.replace("</Relationships>", () => {
|
|
74
|
+
return `<Relationship Id="${rId}" Type="${WORKSHEET_REL_TYPE}" Target="worksheets/sheet${sheet.index}.xml"/></Relationships>`;
|
|
75
|
+
}));
|
|
76
|
+
zip.set(filename, EMPTY_SHEET_XML);
|
|
77
|
+
existing = EMPTY_SHEET_XML;
|
|
84
78
|
}
|
|
85
|
-
if (
|
|
86
|
-
let xml = sheet.modify(
|
|
79
|
+
if (null === existing) continue;
|
|
80
|
+
let xml = sheet.modify(existing);
|
|
87
81
|
if (sheet.addLogo && logo) {
|
|
88
82
|
drawingCounter++;
|
|
89
83
|
const drawingNum = drawingCounter;
|
|
90
84
|
const logoWidthEmu = Math.round((sheet.logoWidthPx ?? LOGO_WIDTH_PX) * PX_TO_EMU);
|
|
91
85
|
const logoHeightEmu = Math.round((sheet.logoHeightPx ?? LOGO_HEIGHT_PX) * PX_TO_EMU);
|
|
92
86
|
const drawingRId = `rIdLogo${drawingNum}`;
|
|
93
|
-
zip.
|
|
94
|
-
zip.
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
let contentTypesXml = await contentTypesFile.async("string");
|
|
87
|
+
zip.set(`xl/drawings/drawing${drawingNum}.xml`, buildDrawingXml(logoWidthEmu, logoHeightEmu));
|
|
88
|
+
zip.set(`xl/drawings/_rels/drawing${drawingNum}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="${IMAGE_REL_TYPE}" Target="../media/image1.png"/></Relationships>`);
|
|
89
|
+
let contentTypesXml = zip.getText("[Content_Types].xml");
|
|
90
|
+
if (null !== contentTypesXml) {
|
|
98
91
|
const drawingPart = `/xl/drawings/drawing${drawingNum}.xml`;
|
|
99
92
|
if (!contentTypesXml.includes(drawingPart)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
100
93
|
return `<Override PartName="${drawingPart}" ContentType="${DRAWING_CONTENT_TYPE}"/></Types>`;
|
|
101
94
|
});
|
|
102
|
-
zip.
|
|
95
|
+
zip.set("[Content_Types].xml", contentTypesXml);
|
|
103
96
|
}
|
|
104
97
|
const sheetRelsPath = `xl/worksheets/_rels/sheet${sheet.index}.xml.rels`;
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}));
|
|
111
|
-
} else zip.file(sheetRelsPath, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`);
|
|
98
|
+
const sheetRelsXml = zip.getText(sheetRelsPath);
|
|
99
|
+
if (null !== sheetRelsXml) zip.set(sheetRelsPath, sheetRelsXml.replace("</Relationships>", () => {
|
|
100
|
+
return `<Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`;
|
|
101
|
+
}));
|
|
102
|
+
else zip.set(sheetRelsPath, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`);
|
|
112
103
|
if (!xml.includes("xmlns:r=")) xml = xml.replace("<worksheet ", `<worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" `);
|
|
113
104
|
xml = xml.replace("</worksheet>", () => {
|
|
114
105
|
return `<drawing r:id="${drawingRId}"/></worksheet>`;
|
|
115
106
|
});
|
|
116
107
|
}
|
|
117
|
-
zip.
|
|
108
|
+
zip.set(filename, xml);
|
|
118
109
|
}
|
|
119
|
-
return zip.
|
|
120
|
-
type: "uint8array",
|
|
121
|
-
compression: "DEFLATE"
|
|
122
|
-
});
|
|
110
|
+
return zip.toBytes();
|
|
123
111
|
};
|
|
124
112
|
//#endregion
|
|
125
113
|
exports.modifyXlsx = modifyXlsx;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getEscapedXml } from "./cell.mjs";
|
|
2
|
+
import { ZipArchive } from "../../zip/_shared/ZipArchive.mjs";
|
|
2
3
|
//#region src/xlsx/_shared/modifyXlsx.ts
|
|
3
4
|
/**
|
|
4
5
|
* Patches an existing .xlsx template: apply per-sheet XML transformations, add
|
|
@@ -45,80 +46,67 @@ const buildDrawingXml = (widthEmu, heightEmu) => {
|
|
|
45
46
|
* @param logo Optional PNG bytes, embedded into sheets with `addLogo`.
|
|
46
47
|
*/
|
|
47
48
|
const modifyXlsx = async (template, sheets, logo) => {
|
|
48
|
-
const zip = await
|
|
49
|
+
const zip = await ZipArchive.load(template);
|
|
49
50
|
if (logo) {
|
|
50
|
-
zip.
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
let contentTypesXml = await contentTypesFile.async("string");
|
|
51
|
+
zip.set("xl/media/image1.png", logo);
|
|
52
|
+
let contentTypesXml = zip.getText("[Content_Types].xml");
|
|
53
|
+
if (null !== contentTypesXml) {
|
|
54
54
|
if (!contentTypesXml.includes(`Extension="png"`)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
55
55
|
return `<Default Extension="png" ContentType="image/png"/></Types>`;
|
|
56
56
|
});
|
|
57
|
-
zip.
|
|
57
|
+
zip.set("[Content_Types].xml", contentTypesXml);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
let drawingCounter = 0;
|
|
61
61
|
for (const sheet of sheets) {
|
|
62
62
|
const filename = `xl/worksheets/sheet${sheet.index}.xml`;
|
|
63
|
-
let existing = zip.
|
|
64
|
-
if (
|
|
63
|
+
let existing = zip.getText(filename);
|
|
64
|
+
if (null === existing && sheet.createIfMissing) {
|
|
65
65
|
const name = sheet.sheetName ?? `Sheet${sheet.index}`;
|
|
66
66
|
const rId = `rId${sheet.index + 10}`;
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
zip.file("xl/_rels/workbook.xml.rels", relsXml.replace("</Relationships>", () => {
|
|
78
|
-
return `<Relationship Id="${rId}" Type="${WORKSHEET_REL_TYPE}" Target="worksheets/sheet${sheet.index}.xml"/></Relationships>`;
|
|
79
|
-
}));
|
|
80
|
-
}
|
|
81
|
-
zip.file(filename, EMPTY_SHEET_XML);
|
|
82
|
-
existing = zip.file(filename);
|
|
67
|
+
const workbookXml = zip.getText("xl/workbook.xml");
|
|
68
|
+
if (null !== workbookXml) zip.set("xl/workbook.xml", workbookXml.replace("</sheets>", () => {
|
|
69
|
+
return `<sheet name="${getEscapedXml(name)}" sheetId="${sheet.index}" r:id="${rId}"/></sheets>`;
|
|
70
|
+
}));
|
|
71
|
+
const relsXml = zip.getText("xl/_rels/workbook.xml.rels");
|
|
72
|
+
if (null !== relsXml) zip.set("xl/_rels/workbook.xml.rels", relsXml.replace("</Relationships>", () => {
|
|
73
|
+
return `<Relationship Id="${rId}" Type="${WORKSHEET_REL_TYPE}" Target="worksheets/sheet${sheet.index}.xml"/></Relationships>`;
|
|
74
|
+
}));
|
|
75
|
+
zip.set(filename, EMPTY_SHEET_XML);
|
|
76
|
+
existing = EMPTY_SHEET_XML;
|
|
83
77
|
}
|
|
84
|
-
if (
|
|
85
|
-
let xml = sheet.modify(
|
|
78
|
+
if (null === existing) continue;
|
|
79
|
+
let xml = sheet.modify(existing);
|
|
86
80
|
if (sheet.addLogo && logo) {
|
|
87
81
|
drawingCounter++;
|
|
88
82
|
const drawingNum = drawingCounter;
|
|
89
83
|
const logoWidthEmu = Math.round((sheet.logoWidthPx ?? LOGO_WIDTH_PX) * PX_TO_EMU);
|
|
90
84
|
const logoHeightEmu = Math.round((sheet.logoHeightPx ?? LOGO_HEIGHT_PX) * PX_TO_EMU);
|
|
91
85
|
const drawingRId = `rIdLogo${drawingNum}`;
|
|
92
|
-
zip.
|
|
93
|
-
zip.
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
let contentTypesXml = await contentTypesFile.async("string");
|
|
86
|
+
zip.set(`xl/drawings/drawing${drawingNum}.xml`, buildDrawingXml(logoWidthEmu, logoHeightEmu));
|
|
87
|
+
zip.set(`xl/drawings/_rels/drawing${drawingNum}.xml.rels`, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="${IMAGE_REL_TYPE}" Target="../media/image1.png"/></Relationships>`);
|
|
88
|
+
let contentTypesXml = zip.getText("[Content_Types].xml");
|
|
89
|
+
if (null !== contentTypesXml) {
|
|
97
90
|
const drawingPart = `/xl/drawings/drawing${drawingNum}.xml`;
|
|
98
91
|
if (!contentTypesXml.includes(drawingPart)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
99
92
|
return `<Override PartName="${drawingPart}" ContentType="${DRAWING_CONTENT_TYPE}"/></Types>`;
|
|
100
93
|
});
|
|
101
|
-
zip.
|
|
94
|
+
zip.set("[Content_Types].xml", contentTypesXml);
|
|
102
95
|
}
|
|
103
96
|
const sheetRelsPath = `xl/worksheets/_rels/sheet${sheet.index}.xml.rels`;
|
|
104
|
-
const
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}));
|
|
110
|
-
} else zip.file(sheetRelsPath, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`);
|
|
97
|
+
const sheetRelsXml = zip.getText(sheetRelsPath);
|
|
98
|
+
if (null !== sheetRelsXml) zip.set(sheetRelsPath, sheetRelsXml.replace("</Relationships>", () => {
|
|
99
|
+
return `<Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`;
|
|
100
|
+
}));
|
|
101
|
+
else zip.set(sheetRelsPath, `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`);
|
|
111
102
|
if (!xml.includes("xmlns:r=")) xml = xml.replace("<worksheet ", `<worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" `);
|
|
112
103
|
xml = xml.replace("</worksheet>", () => {
|
|
113
104
|
return `<drawing r:id="${drawingRId}"/></worksheet>`;
|
|
114
105
|
});
|
|
115
106
|
}
|
|
116
|
-
zip.
|
|
107
|
+
zip.set(filename, xml);
|
|
117
108
|
}
|
|
118
|
-
return zip.
|
|
119
|
-
type: "uint8array",
|
|
120
|
-
compression: "DEFLATE"
|
|
121
|
-
});
|
|
109
|
+
return zip.toBytes();
|
|
122
110
|
};
|
|
123
111
|
//#endregion
|
|
124
112
|
export { modifyXlsx };
|
|
@@ -4,7 +4,6 @@ const require_xlsx__shared_cell = require("../_shared/cell.cjs");
|
|
|
4
4
|
const require_xlsx__shared_sheet = require("../_shared/sheet.cjs");
|
|
5
5
|
const require_xlsx__shared_createXlsx = require("../_shared/createXlsx.cjs");
|
|
6
6
|
const require_xlsx__shared_modifyXlsx = require("../_shared/modifyXlsx.cjs");
|
|
7
|
-
require("../_shared/index.cjs");
|
|
8
7
|
exports.buildCellXml = require_xlsx__shared_cell.buildCellXml;
|
|
9
8
|
exports.createXlsx = require_xlsx__shared_createXlsx.createXlsx;
|
|
10
9
|
exports.createXlsxBytes = require_xlsx__shared_createXlsx.createXlsxBytes;
|
|
@@ -3,5 +3,4 @@ import { buildCellXml, getCellColNum, getCellValue, getEscapedXml, setCell } fro
|
|
|
3
3
|
import { getSanitisedSheetName, getUniqueSheetNames } from "../_shared/sheet.mjs";
|
|
4
4
|
import { createXlsx, createXlsxBytes } from "../_shared/createXlsx.mjs";
|
|
5
5
|
import { modifyXlsx } from "../_shared/modifyXlsx.mjs";
|
|
6
|
-
import "../_shared/index.mjs";
|
|
7
6
|
export { buildCellXml, createXlsx, createXlsxBytes, getCellColNum, getCellValue, getColumLetter, getColumnWidth, getEscapedXml, getSanitisedSheetName, getUniqueSheetNames, modifyXlsx, setCell };
|
|
@@ -4,7 +4,6 @@ const require_xlsx__shared_cell = require("../_shared/cell.cjs");
|
|
|
4
4
|
const require_xlsx__shared_sheet = require("../_shared/sheet.cjs");
|
|
5
5
|
const require_xlsx__shared_createXlsx = require("../_shared/createXlsx.cjs");
|
|
6
6
|
const require_xlsx__shared_modifyXlsx = require("../_shared/modifyXlsx.cjs");
|
|
7
|
-
require("../_shared/index.cjs");
|
|
8
7
|
exports.buildCellXml = require_xlsx__shared_cell.buildCellXml;
|
|
9
8
|
exports.createXlsx = require_xlsx__shared_createXlsx.createXlsx;
|
|
10
9
|
exports.createXlsxBytes = require_xlsx__shared_createXlsx.createXlsxBytes;
|
|
@@ -3,5 +3,4 @@ import { buildCellXml, getCellColNum, getCellValue, getEscapedXml, setCell } fro
|
|
|
3
3
|
import { getSanitisedSheetName, getUniqueSheetNames } from "../_shared/sheet.mjs";
|
|
4
4
|
import { createXlsx, createXlsxBytes } from "../_shared/createXlsx.mjs";
|
|
5
5
|
import { modifyXlsx } from "../_shared/modifyXlsx.mjs";
|
|
6
|
-
import "../_shared/index.mjs";
|
|
7
6
|
export { buildCellXml, createXlsx, createXlsxBytes, getCellColNum, getCellValue, getColumLetter, getColumnWidth, getEscapedXml, getSanitisedSheetName, getUniqueSheetNames, modifyXlsx, setCell };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_zip__shared_readZip = require("./readZip.cjs");
|
|
3
|
+
const require_zip__shared_writeZip = require("./writeZip.cjs");
|
|
4
|
+
//#region src/zip/_shared/ZipArchive.ts
|
|
5
|
+
/**
|
|
6
|
+
* An in-memory ZIP archive.
|
|
7
|
+
*
|
|
8
|
+
* Contents are held decompressed, so reads are synchronous and only `load`,
|
|
9
|
+
* `toBytes` and `toBlob` are async. That suits the archives this library deals
|
|
10
|
+
* with — office documents of a few hundred kilobytes — and keeps call sites flat.
|
|
11
|
+
*
|
|
12
|
+
* Insertion order is preserved, and overwriting an existing path keeps its
|
|
13
|
+
* position, so a patched document comes back out in its original part order.
|
|
14
|
+
*/
|
|
15
|
+
var ZipArchive = class ZipArchive {
|
|
16
|
+
entries = /* @__PURE__ */ new Map();
|
|
17
|
+
static async load(bytes) {
|
|
18
|
+
const archive = new ZipArchive();
|
|
19
|
+
for (const [name, content] of await require_zip__shared_readZip.getZipEntries(bytes)) archive.entries.set(name, content);
|
|
20
|
+
return archive;
|
|
21
|
+
}
|
|
22
|
+
has(path) {
|
|
23
|
+
return this.entries.has(path);
|
|
24
|
+
}
|
|
25
|
+
getBytes(path) {
|
|
26
|
+
return this.entries.get(path) ?? null;
|
|
27
|
+
}
|
|
28
|
+
getText(path) {
|
|
29
|
+
const content = this.entries.get(path);
|
|
30
|
+
return content ? new TextDecoder().decode(content) : null;
|
|
31
|
+
}
|
|
32
|
+
set(path, content) {
|
|
33
|
+
this.entries.set(path, "string" === typeof content ? new TextEncoder().encode(content) : content);
|
|
34
|
+
}
|
|
35
|
+
delete(path) {
|
|
36
|
+
return this.entries.delete(path);
|
|
37
|
+
}
|
|
38
|
+
list() {
|
|
39
|
+
return [...this.entries.keys()];
|
|
40
|
+
}
|
|
41
|
+
async toBytes() {
|
|
42
|
+
return require_zip__shared_writeZip.getZipBytes(this.entries);
|
|
43
|
+
}
|
|
44
|
+
async toBlob(mimeType = "application/zip") {
|
|
45
|
+
return new Blob([await this.toBytes()], { type: mimeType });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
exports.ZipArchive = ZipArchive;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/zip/_shared/ZipArchive.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* An in-memory ZIP archive.
|
|
4
|
+
*
|
|
5
|
+
* Contents are held decompressed, so reads are synchronous and only `load`,
|
|
6
|
+
* `toBytes` and `toBlob` are async. That suits the archives this library deals
|
|
7
|
+
* with — office documents of a few hundred kilobytes — and keeps call sites flat.
|
|
8
|
+
*
|
|
9
|
+
* Insertion order is preserved, and overwriting an existing path keeps its
|
|
10
|
+
* position, so a patched document comes back out in its original part order.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ZipArchive {
|
|
13
|
+
private readonly entries;
|
|
14
|
+
static load(bytes: Uint8Array): Promise<ZipArchive>;
|
|
15
|
+
has(path: string): boolean;
|
|
16
|
+
getBytes(path: string): Uint8Array | null;
|
|
17
|
+
getText(path: string): string | null;
|
|
18
|
+
set(path: string, content: string | Uint8Array): void;
|
|
19
|
+
delete(path: string): boolean;
|
|
20
|
+
list(): string[];
|
|
21
|
+
toBytes(): Promise<Uint8Array>;
|
|
22
|
+
toBlob(mimeType?: string): Promise<Blob>;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
//#region src/zip/_shared/ZipArchive.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* An in-memory ZIP archive.
|
|
4
|
+
*
|
|
5
|
+
* Contents are held decompressed, so reads are synchronous and only `load`,
|
|
6
|
+
* `toBytes` and `toBlob` are async. That suits the archives this library deals
|
|
7
|
+
* with — office documents of a few hundred kilobytes — and keeps call sites flat.
|
|
8
|
+
*
|
|
9
|
+
* Insertion order is preserved, and overwriting an existing path keeps its
|
|
10
|
+
* position, so a patched document comes back out in its original part order.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ZipArchive {
|
|
13
|
+
private readonly entries;
|
|
14
|
+
static load(bytes: Uint8Array): Promise<ZipArchive>;
|
|
15
|
+
has(path: string): boolean;
|
|
16
|
+
getBytes(path: string): Uint8Array | null;
|
|
17
|
+
getText(path: string): string | null;
|
|
18
|
+
set(path: string, content: string | Uint8Array): void;
|
|
19
|
+
delete(path: string): boolean;
|
|
20
|
+
list(): string[];
|
|
21
|
+
toBytes(): Promise<Uint8Array>;
|
|
22
|
+
toBlob(mimeType?: string): Promise<Blob>;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getZipEntries } from "./readZip.mjs";
|
|
2
|
+
import { getZipBytes } from "./writeZip.mjs";
|
|
3
|
+
//#region src/zip/_shared/ZipArchive.ts
|
|
4
|
+
/**
|
|
5
|
+
* An in-memory ZIP archive.
|
|
6
|
+
*
|
|
7
|
+
* Contents are held decompressed, so reads are synchronous and only `load`,
|
|
8
|
+
* `toBytes` and `toBlob` are async. That suits the archives this library deals
|
|
9
|
+
* with — office documents of a few hundred kilobytes — and keeps call sites flat.
|
|
10
|
+
*
|
|
11
|
+
* Insertion order is preserved, and overwriting an existing path keeps its
|
|
12
|
+
* position, so a patched document comes back out in its original part order.
|
|
13
|
+
*/
|
|
14
|
+
var ZipArchive = class ZipArchive {
|
|
15
|
+
entries = /* @__PURE__ */ new Map();
|
|
16
|
+
static async load(bytes) {
|
|
17
|
+
const archive = new ZipArchive();
|
|
18
|
+
for (const [name, content] of await getZipEntries(bytes)) archive.entries.set(name, content);
|
|
19
|
+
return archive;
|
|
20
|
+
}
|
|
21
|
+
has(path) {
|
|
22
|
+
return this.entries.has(path);
|
|
23
|
+
}
|
|
24
|
+
getBytes(path) {
|
|
25
|
+
return this.entries.get(path) ?? null;
|
|
26
|
+
}
|
|
27
|
+
getText(path) {
|
|
28
|
+
const content = this.entries.get(path);
|
|
29
|
+
return content ? new TextDecoder().decode(content) : null;
|
|
30
|
+
}
|
|
31
|
+
set(path, content) {
|
|
32
|
+
this.entries.set(path, "string" === typeof content ? new TextEncoder().encode(content) : content);
|
|
33
|
+
}
|
|
34
|
+
delete(path) {
|
|
35
|
+
return this.entries.delete(path);
|
|
36
|
+
}
|
|
37
|
+
list() {
|
|
38
|
+
return [...this.entries.keys()];
|
|
39
|
+
}
|
|
40
|
+
async toBytes() {
|
|
41
|
+
return getZipBytes(this.entries);
|
|
42
|
+
}
|
|
43
|
+
async toBlob(mimeType = "application/zip") {
|
|
44
|
+
return new Blob([await this.toBytes()], { type: mimeType });
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
//#endregion
|
|
48
|
+
export { ZipArchive };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/zip/_shared/crc32.ts
|
|
3
|
+
const POLYNOMIAL = 3988292384;
|
|
4
|
+
let table = null;
|
|
5
|
+
const getTable = () => {
|
|
6
|
+
if (table) return table;
|
|
7
|
+
const next = /* @__PURE__ */ new Uint32Array(256);
|
|
8
|
+
for (let index = 0; index < 256; index++) {
|
|
9
|
+
let value = index;
|
|
10
|
+
for (let bit = 0; bit < 8; bit++) value = 1 === (value & 1) ? POLYNOMIAL ^ value >>> 1 : value >>> 1;
|
|
11
|
+
next[index] = value >>> 0;
|
|
12
|
+
}
|
|
13
|
+
table = next;
|
|
14
|
+
return table;
|
|
15
|
+
};
|
|
16
|
+
/** CRC-32 (IEEE 802.3) checksum, as required by the ZIP file format. */
|
|
17
|
+
const getCrc32 = (bytes) => {
|
|
18
|
+
const lookup = getTable();
|
|
19
|
+
let crc = 4294967295;
|
|
20
|
+
for (let index = 0; index < bytes.length; index++) crc = lookup[(crc ^ bytes[index]) & 255] ^ crc >>> 8;
|
|
21
|
+
return (crc ^ 4294967295) >>> 0;
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
exports.getCrc32 = getCrc32;
|