@8ms/helpers 3.0.22 → 3.0.24
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/_virtual/_rolldown/runtime.cjs +1 -1
- package/dist/adverity/adverity.d.cts +0 -1
- package/dist/adverity/adverity.d.mts +0 -1
- package/dist/adverity/server/getJobs.d.cts +2 -0
- package/dist/adverity/server/getJobs.d.mts +2 -0
- package/dist/api/ApiResponseClass.d.cts +1 -6
- package/dist/api/ApiResponseClass.d.mts +1 -6
- package/dist/api/api.d.cts +0 -1
- package/dist/api/api.d.mts +0 -1
- package/dist/api/deleteRequest.d.cts +0 -1
- package/dist/api/deleteRequest.d.mts +0 -1
- package/dist/api/functions.d.cts +0 -1
- package/dist/api/functions.d.mts +0 -1
- package/dist/api/get.d.cts +0 -1
- package/dist/api/get.d.mts +0 -1
- package/dist/api/post.d.cts +0 -1
- package/dist/api/post.d.mts +0 -1
- package/dist/atInternet/atInternet.d.cts +0 -1
- package/dist/atInternet/atInternet.d.mts +0 -1
- package/dist/aws/cloudWatchLog/server/AwsCloudWatchLog.d.cts +0 -1
- package/dist/aws/cloudWatchLog/server/AwsCloudWatchLog.d.mts +0 -1
- package/dist/aws/cloudWatchLog/server/logEvent.d.cts +1 -0
- package/dist/aws/cloudWatchLog/server/logEvent.d.mts +1 -0
- package/dist/aws/cloudWatchMetric/server/AwsCloudWatchMetric.d.cts +0 -1
- package/dist/aws/cloudWatchMetric/server/AwsCloudWatchMetric.d.mts +0 -1
- package/dist/aws/cloudWatchMetric/server/logMetric.d.cts +1 -1
- package/dist/aws/cloudWatchMetric/server/logMetric.d.mts +1 -1
- package/dist/aws/ec2/server/AwsEc2.d.cts +0 -1
- package/dist/aws/ec2/server/AwsEc2.d.mts +0 -1
- package/dist/aws/ecs/server/AwsEcs.d.cts +0 -1
- package/dist/aws/ecs/server/AwsEcs.d.mts +0 -1
- package/dist/aws/glue/server/AwsGlue.cjs +2 -1
- package/dist/aws/glue/server/AwsGlue.d.cts +0 -1
- package/dist/aws/glue/server/AwsGlue.d.mts +0 -1
- package/dist/aws/glue/server/AwsGlue.mjs +2 -1
- package/dist/aws/lambda/server/AwsLambda.cjs +10 -8
- package/dist/aws/lambda/server/AwsLambda.d.cts +0 -1
- package/dist/aws/lambda/server/AwsLambda.d.mts +0 -1
- package/dist/aws/lambda/server/AwsLambda.mjs +10 -8
- package/dist/aws/s3/server/AwsS3.cjs +3 -2
- package/dist/aws/s3/server/AwsS3.d.cts +1 -1
- package/dist/aws/s3/server/AwsS3.d.mts +1 -1
- package/dist/aws/s3/server/AwsS3.mjs +3 -2
- package/dist/aws/s3/server/payload.d.cts +0 -1
- package/dist/aws/s3/server/payload.d.mts +0 -1
- package/dist/aws/ses/server/AwsSes.cjs +4 -11
- package/dist/aws/ses/server/AwsSes.d.cts +3 -4
- package/dist/aws/ses/server/AwsSes.d.mts +3 -4
- package/dist/aws/ses/server/AwsSes.mjs +4 -11
- package/dist/aws/ses/server/SimpleEmail.cjs +10 -11
- package/dist/aws/ses/server/SimpleEmail.d.cts +3 -12
- package/dist/aws/ses/server/SimpleEmail.d.mts +3 -12
- package/dist/aws/ses/server/SimpleEmail.mjs +10 -11
- package/dist/aws/sqs/server/AwsSqs.d.cts +0 -1
- package/dist/aws/sqs/server/AwsSqs.d.mts +0 -1
- package/dist/aws/ssm/server/AwsSsm.cjs +5 -4
- package/dist/aws/ssm/server/AwsSsm.d.cts +0 -1
- package/dist/aws/ssm/server/AwsSsm.d.mts +0 -1
- package/dist/aws/ssm/server/AwsSsm.mjs +5 -4
- package/dist/brightData/serpApi/server/buildGoogleSerpUrl.cjs +0 -2
- package/dist/brightData/serpApi/server/buildGoogleSerpUrl.mjs +0 -2
- package/dist/brightData/serpApi/server/buildGoogleTrendsUrl.cjs +0 -1
- package/dist/brightData/serpApi/server/buildGoogleTrendsUrl.mjs +0 -1
- package/dist/brightData/serpApi/server/getAsyncRequestId.d.cts +1 -0
- package/dist/brightData/serpApi/server/getAsyncRequestId.d.mts +1 -0
- package/dist/brightData/serpApi/server/getAsyncResults.cjs +7 -4
- package/dist/brightData/serpApi/server/getAsyncResults.d.cts +1 -1
- package/dist/brightData/serpApi/server/getAsyncResults.d.mts +1 -1
- package/dist/brightData/serpApi/server/getAsyncResults.mjs +7 -4
- package/dist/brightData/serpApi/server/getRealtime.d.cts +0 -1
- package/dist/brightData/serpApi/server/getRealtime.d.mts +0 -1
- package/dist/brightData/webScraperIde/server/getBatch.d.cts +0 -1
- package/dist/brightData/webScraperIde/server/getBatch.d.mts +0 -1
- package/dist/brightData/webScraperIde/server/getRealtime.cjs +10 -6
- package/dist/brightData/webScraperIde/server/getRealtime.d.cts +0 -1
- package/dist/brightData/webScraperIde/server/getRealtime.d.mts +0 -1
- package/dist/brightData/webScraperIde/server/getRealtime.mjs +10 -6
- package/dist/date/calculation.cjs +27 -24
- package/dist/date/calculation.d.cts +0 -1
- package/dist/date/calculation.d.mts +0 -1
- package/dist/date/calculation.mjs +27 -24
- package/dist/date/date.d.cts +0 -1
- package/dist/date/date.d.mts +0 -1
- package/dist/date/financialYear.d.cts +0 -1
- package/dist/date/financialYear.d.mts +0 -1
- package/dist/date/format.d.cts +0 -1
- package/dist/date/format.d.mts +0 -1
- package/dist/drizzle/server/Drizzle.d.cts +0 -1
- package/dist/drizzle/server/Drizzle.d.mts +0 -1
- package/dist/emsApi/awsTs/get.cjs +2 -1
- package/dist/emsApi/awsTs/get.d.cts +1 -0
- package/dist/emsApi/awsTs/get.d.mts +1 -0
- package/dist/emsApi/awsTs/get.mjs +2 -1
- package/dist/emsApi/awsTs/post.cjs +2 -1
- package/dist/emsApi/awsTs/post.d.cts +1 -0
- package/dist/emsApi/awsTs/post.d.mts +1 -0
- package/dist/emsApi/awsTs/post.mjs +2 -1
- package/dist/emsApi/vercel/get.cjs +2 -1
- package/dist/emsApi/vercel/get.d.cts +1 -0
- package/dist/emsApi/vercel/get.d.mts +1 -0
- package/dist/emsApi/vercel/get.mjs +2 -1
- package/dist/emsApi/vercel/post.cjs +2 -1
- package/dist/emsApi/vercel/post.d.cts +1 -0
- package/dist/emsApi/vercel/post.d.mts +1 -0
- package/dist/emsApi/vercel/post.mjs +2 -1
- package/dist/eskimi/eskimi.d.cts +0 -1
- package/dist/eskimi/eskimi.d.mts +0 -1
- package/dist/googleAds/keywordPlanner/server/googleAdsKeywordPlanner.d.cts +0 -1
- package/dist/googleAds/keywordPlanner/server/googleAdsKeywordPlanner.d.mts +0 -1
- package/dist/googleAds/server/GoogleAds.d.cts +0 -1
- package/dist/googleAds/server/GoogleAds.d.mts +0 -1
- package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.d.cts +0 -1
- package/dist/googleCloud/bigquery/server/GoogleCloudBigquery.d.mts +0 -1
- package/dist/googleCloud/bigquery/server/loadData.d.cts +1 -7
- package/dist/googleCloud/bigquery/server/loadData.d.mts +1 -7
- package/dist/googleCloud/sheets/server/GoogleCloudSheets.d.cts +1 -2
- package/dist/googleCloud/sheets/server/GoogleCloudSheets.d.mts +1 -2
- package/dist/googleCloud/storage/server/GoogleCloudStorage.d.cts +0 -1
- package/dist/googleCloud/storage/server/GoogleCloudStorage.d.mts +0 -1
- package/dist/googlePageSpeed/server/GooglePageSpeed.cjs +2 -1
- package/dist/googlePageSpeed/server/GooglePageSpeed.d.cts +0 -1
- package/dist/googlePageSpeed/server/GooglePageSpeed.d.mts +0 -1
- package/dist/googlePageSpeed/server/GooglePageSpeed.mjs +2 -1
- package/dist/googleSearchIncidents/server/googleSearchIncidents.d.cts +0 -1
- package/dist/googleSearchIncidents/server/googleSearchIncidents.d.mts +0 -1
- package/dist/greenDomain/server/greenDomain.cjs +2 -1
- package/dist/greenDomain/server/greenDomain.d.cts +0 -1
- package/dist/greenDomain/server/greenDomain.d.mts +0 -1
- package/dist/greenDomain/server/greenDomain.mjs +2 -1
- package/dist/littleWarden/server/LittleWarden.cjs +2 -1
- package/dist/littleWarden/server/LittleWarden.d.cts +0 -1
- package/dist/littleWarden/server/LittleWarden.d.mts +0 -1
- package/dist/littleWarden/server/LittleWarden.mjs +2 -1
- package/dist/littleWarden/server/littleWardenAttrs.d.cts +3 -10
- package/dist/littleWarden/server/littleWardenAttrs.d.mts +3 -10
- package/dist/lumar/api/server/buildRequest.cjs +0 -1
- package/dist/lumar/api/server/buildRequest.d.cts +1 -0
- package/dist/lumar/api/server/buildRequest.d.mts +1 -0
- package/dist/lumar/api/server/buildRequest.mjs +0 -1
- package/dist/lumar/api/server/getData.d.cts +1 -0
- package/dist/lumar/api/server/getData.d.mts +1 -0
- package/dist/lumar/graphql/server/getData.d.cts +1 -0
- package/dist/lumar/graphql/server/getData.d.mts +1 -0
- package/dist/lumar/graphql/server/queries/getCrawls.d.cts +1 -4
- package/dist/lumar/graphql/server/queries/getCrawls.d.mts +1 -4
- package/dist/lumar/graphql/server/queries/getReportDifferences.d.cts +1 -5
- package/dist/lumar/graphql/server/queries/getReportDifferences.d.mts +1 -5
- package/dist/lumar/graphql/server/queries/getRows.d.cts +1 -11
- package/dist/lumar/graphql/server/queries/getRows.d.mts +1 -11
- package/dist/lumar/graphql/server/queries/getTotals.d.cts +1 -7
- package/dist/lumar/graphql/server/queries/getTotals.d.mts +1 -7
- package/dist/myTarget/server/myTarget.d.cts +0 -1
- package/dist/myTarget/server/myTarget.d.mts +0 -1
- package/dist/nextAuth/nextAuth.d.cts +0 -1
- package/dist/nextAuth/nextAuth.d.mts +0 -1
- package/dist/nextJs/client/LazyLoad.d.cts +0 -1
- package/dist/nextJs/client/LazyLoad.d.mts +0 -1
- package/dist/onePassword/server/OnePassword.d.cts +0 -1
- package/dist/onePassword/server/OnePassword.d.mts +0 -1
- package/dist/openAi/server/OpenAi.d.cts +0 -1
- package/dist/openAi/server/OpenAi.d.mts +0 -1
- package/dist/prisma/server/Prisma.d.cts +0 -1
- package/dist/prisma/server/Prisma.d.mts +0 -1
- package/dist/snapchat/server/Snapchat.cjs +3 -2
- package/dist/snapchat/server/Snapchat.d.cts +0 -1
- package/dist/snapchat/server/Snapchat.d.mts +0 -1
- package/dist/snapchat/server/Snapchat.mjs +3 -2
- package/dist/stream/server/sort.d.cts +0 -1
- package/dist/stream/server/sort.d.mts +0 -1
- package/dist/swr/client/swr.d.cts +1 -0
- package/dist/swr/client/swr.d.mts +1 -0
- package/dist/upTimeRobot/server/UpTimeRobot.d.cts +0 -1
- package/dist/upTimeRobot/server/UpTimeRobot.d.mts +0 -1
- package/dist/util/defaultTo.cjs +6 -3
- package/dist/util/defaultTo.mjs +6 -3
- package/dist/util/server/getBrotliCompressed.d.cts +0 -1
- package/dist/util/server/getBrotliCompressed.d.mts +0 -1
- package/dist/util/server/getBrotliDecompressed.d.cts +0 -1
- package/dist/util/server/getBrotliDecompressed.d.mts +0 -1
- package/dist/util/server/getGzipCompressed.d.cts +0 -1
- package/dist/util/server/getGzipCompressed.d.mts +0 -1
- package/dist/util/server/getGzipDecompressed.d.cts +0 -1
- package/dist/util/server/getGzipDecompressed.d.mts +0 -1
- package/dist/xlsx/cell.cjs +102 -0
- package/dist/xlsx/cell.d.cts +38 -0
- package/dist/xlsx/cell.d.mts +38 -0
- package/dist/xlsx/cell.mjs +97 -0
- package/dist/xlsx/column.cjs +37 -0
- package/dist/xlsx/column.d.cts +23 -0
- package/dist/xlsx/column.d.mts +23 -0
- package/dist/xlsx/column.mjs +35 -0
- package/dist/xlsx/createXlsx.cjs +138 -0
- package/dist/xlsx/createXlsx.d.cts +18 -0
- package/dist/xlsx/createXlsx.d.mts +18 -0
- package/dist/xlsx/createXlsx.mjs +136 -0
- package/dist/xlsx/index.cjs +18 -0
- package/dist/xlsx/index.d.cts +6 -0
- package/dist/xlsx/index.d.mts +6 -0
- package/dist/xlsx/index.mjs +6 -0
- package/dist/xlsx/modifyXlsx.cjs +125 -0
- package/dist/xlsx/modifyXlsx.d.cts +24 -0
- package/dist/xlsx/modifyXlsx.d.mts +24 -0
- package/dist/xlsx/modifyXlsx.mjs +124 -0
- package/dist/xlsx/sheet.cjs +36 -0
- package/dist/xlsx/sheet.d.cts +29 -0
- package/dist/xlsx/sheet.d.mts +29 -0
- package/dist/xlsx/sheet.mjs +34 -0
- package/package.json +103 -57
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { getEscapedXml } from "./cell.mjs";
|
|
2
|
+
//#region src/xlsx/modifyXlsx.ts
|
|
3
|
+
/**
|
|
4
|
+
* Patches an existing .xlsx template: apply per-sheet XML transformations, add
|
|
5
|
+
* sheets that are not in the template, and optionally embed a logo image.
|
|
6
|
+
*
|
|
7
|
+
* Takes and returns bytes rather than file paths, so it has no filesystem
|
|
8
|
+
* dependency and runs anywhere. Callers that work from disk read the template
|
|
9
|
+
* themselves and hand over the buffer.
|
|
10
|
+
*
|
|
11
|
+
* Use this when the output must keep a branded template's styling; use
|
|
12
|
+
* `createXlsx` when building a workbook from nothing.
|
|
13
|
+
*/
|
|
14
|
+
/** 1 screen pixel at 96 DPI equals 9525 English Metric Units in OOXML. */
|
|
15
|
+
const PX_TO_EMU = 9525;
|
|
16
|
+
/** Default logo box, sized for a typical wide wordmark. */
|
|
17
|
+
const LOGO_WIDTH_PX = 500;
|
|
18
|
+
const LOGO_HEIGHT_PX = 77;
|
|
19
|
+
const DRAWING_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing";
|
|
20
|
+
const IMAGE_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
|
|
21
|
+
const WORKSHEET_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet";
|
|
22
|
+
const DRAWING_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.drawing+xml";
|
|
23
|
+
/**
|
|
24
|
+
* Minimal valid worksheet XML used when `createIfMissing` adds a sheet.
|
|
25
|
+
*
|
|
26
|
+
* <sheetData></sheetData> must not be self-closing: setCell's new-row path
|
|
27
|
+
* searches for the literal closing tag.
|
|
28
|
+
*/
|
|
29
|
+
const EMPTY_SHEET_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\"><sheetData></sheetData></worksheet>";
|
|
30
|
+
/**
|
|
31
|
+
* Drawing XML for one embedded image, anchored to cell B2 so it sits just below
|
|
32
|
+
* the header row.
|
|
33
|
+
*
|
|
34
|
+
* The image relationship is assumed to be registered as "rId1" in the sibling
|
|
35
|
+
* .rels file.
|
|
36
|
+
*/
|
|
37
|
+
const buildDrawingXml = (widthEmu, heightEmu) => {
|
|
38
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><xdr:oneCellAnchor><xdr:from><xdr:col>1</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>1</xdr:row><xdr:rowOff>0</xdr:rowOff></xdr:from><xdr:ext cx="${widthEmu}" cy="${heightEmu}"/><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="2" name="Logo"/><xdr:cNvPicPr><a:picLocks noChangeAspect="1"/></xdr:cNvPicPr></xdr:nvPicPr><xdr:blipFill><a:blip r:embed="rId1"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="${widthEmu}" cy="${heightEmu}"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic><xdr:clientData/></xdr:oneCellAnchor></xdr:wsDr>`;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Apply per-sheet transformations to a template workbook.
|
|
42
|
+
*
|
|
43
|
+
* @param template The .xlsx template as raw bytes.
|
|
44
|
+
* @param sheets One entry per sheet to touch, keyed by its 1-indexed position.
|
|
45
|
+
* @param logo Optional PNG bytes, embedded into sheets with `addLogo`.
|
|
46
|
+
*/
|
|
47
|
+
const modifyXlsx = async (template, sheets, logo) => {
|
|
48
|
+
const zip = await (await import("jszip")).default.loadAsync(template);
|
|
49
|
+
if (logo) {
|
|
50
|
+
zip.file("xl/media/image1.png", logo);
|
|
51
|
+
const contentTypesFile = zip.file("[Content_Types].xml");
|
|
52
|
+
if (contentTypesFile) {
|
|
53
|
+
let contentTypesXml = await contentTypesFile.async("string");
|
|
54
|
+
if (!contentTypesXml.includes(`Extension="png"`)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
55
|
+
return `<Default Extension="png" ContentType="image/png"/></Types>`;
|
|
56
|
+
});
|
|
57
|
+
zip.file("[Content_Types].xml", contentTypesXml);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
let drawingCounter = 0;
|
|
61
|
+
for (const sheet of sheets) {
|
|
62
|
+
const filename = `xl/worksheets/sheet${sheet.index}.xml`;
|
|
63
|
+
let existing = zip.file(filename);
|
|
64
|
+
if (!existing && sheet.createIfMissing) {
|
|
65
|
+
const name = sheet.sheetName ?? `Sheet${sheet.index}`;
|
|
66
|
+
const rId = `rId${sheet.index + 10}`;
|
|
67
|
+
const workbookFile = zip.file("xl/workbook.xml");
|
|
68
|
+
if (workbookFile) {
|
|
69
|
+
const workbookXml = await workbookFile.async("string");
|
|
70
|
+
zip.file("xl/workbook.xml", workbookXml.replace("</sheets>", () => {
|
|
71
|
+
return `<sheet name="${getEscapedXml(name)}" sheetId="${sheet.index}" r:id="${rId}"/></sheets>`;
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
const relsFile = zip.file("xl/_rels/workbook.xml.rels");
|
|
75
|
+
if (relsFile) {
|
|
76
|
+
const relsXml = await relsFile.async("string");
|
|
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);
|
|
83
|
+
}
|
|
84
|
+
if (!existing) continue;
|
|
85
|
+
let xml = sheet.modify(await existing.async("string"));
|
|
86
|
+
if (sheet.addLogo && logo) {
|
|
87
|
+
drawingCounter++;
|
|
88
|
+
const drawingNum = drawingCounter;
|
|
89
|
+
const logoWidthEmu = Math.round((sheet.logoWidthPx ?? LOGO_WIDTH_PX) * PX_TO_EMU);
|
|
90
|
+
const logoHeightEmu = Math.round((sheet.logoHeightPx ?? LOGO_HEIGHT_PX) * PX_TO_EMU);
|
|
91
|
+
const drawingRId = `rIdLogo${drawingNum}`;
|
|
92
|
+
zip.file(`xl/drawings/drawing${drawingNum}.xml`, buildDrawingXml(logoWidthEmu, logoHeightEmu));
|
|
93
|
+
zip.file(`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>`);
|
|
94
|
+
const contentTypesFile = zip.file("[Content_Types].xml");
|
|
95
|
+
if (contentTypesFile) {
|
|
96
|
+
let contentTypesXml = await contentTypesFile.async("string");
|
|
97
|
+
const drawingPart = `/xl/drawings/drawing${drawingNum}.xml`;
|
|
98
|
+
if (!contentTypesXml.includes(drawingPart)) contentTypesXml = contentTypesXml.replace("</Types>", () => {
|
|
99
|
+
return `<Override PartName="${drawingPart}" ContentType="${DRAWING_CONTENT_TYPE}"/></Types>`;
|
|
100
|
+
});
|
|
101
|
+
zip.file("[Content_Types].xml", contentTypesXml);
|
|
102
|
+
}
|
|
103
|
+
const sheetRelsPath = `xl/worksheets/_rels/sheet${sheet.index}.xml.rels`;
|
|
104
|
+
const sheetRelsFile = zip.file(sheetRelsPath);
|
|
105
|
+
if (sheetRelsFile) {
|
|
106
|
+
const relsXml = await sheetRelsFile.async("string");
|
|
107
|
+
zip.file(sheetRelsPath, relsXml.replace("</Relationships>", () => {
|
|
108
|
+
return `<Relationship Id="${drawingRId}" Type="${DRAWING_REL_TYPE}" Target="../drawings/drawing${drawingNum}.xml"/></Relationships>`;
|
|
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>`);
|
|
111
|
+
if (!xml.includes("xmlns:r=")) xml = xml.replace("<worksheet ", `<worksheet xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" `);
|
|
112
|
+
xml = xml.replace("</worksheet>", () => {
|
|
113
|
+
return `<drawing r:id="${drawingRId}"/></worksheet>`;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
zip.file(filename, xml);
|
|
117
|
+
}
|
|
118
|
+
return zip.generateAsync({
|
|
119
|
+
type: "uint8array",
|
|
120
|
+
compression: "DEFLATE"
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
//#endregion
|
|
124
|
+
export { modifyXlsx };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/xlsx/sheet.ts
|
|
3
|
+
/** Excel refuses to open a workbook whose sheet name exceeds 31 characters. */
|
|
4
|
+
const SHEET_NAME_MAX_LENGTH = 31;
|
|
5
|
+
/**
|
|
6
|
+
* Coerce a sheet name into something Excel will accept: no []:*?/\ characters,
|
|
7
|
+
* no wrapping apostrophes, at most 31 characters, and never empty.
|
|
8
|
+
*
|
|
9
|
+
* Uniqueness is handled separately, since that needs the whole set.
|
|
10
|
+
*/
|
|
11
|
+
const getSanitisedSheetName = (name) => {
|
|
12
|
+
const cleaned = (name || "").replace(/[[\]:*?/\\]/g, "_").replace(/^'+|'+$/g, "").trim().slice(0, SHEET_NAME_MAX_LENGTH);
|
|
13
|
+
return "" === cleaned ? "Sheet" : cleaned;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Sanitise every sheet name and break collisions with _2, _3, … while staying
|
|
17
|
+
* inside the 31 character limit. Excel rejects duplicate names outright, so this
|
|
18
|
+
* cannot be left to chance once sheets are generated from data.
|
|
19
|
+
*/
|
|
20
|
+
const getUniqueSheetNames = (sheets) => {
|
|
21
|
+
const used = {};
|
|
22
|
+
return sheets.map((sheet) => {
|
|
23
|
+
const base = getSanitisedSheetName(sheet.name);
|
|
24
|
+
const key = base.toLowerCase();
|
|
25
|
+
if (!(key in used)) {
|
|
26
|
+
used[key] = 1;
|
|
27
|
+
return base;
|
|
28
|
+
}
|
|
29
|
+
used[key] += 1;
|
|
30
|
+
const suffix = `_${used[key]}`;
|
|
31
|
+
return base.slice(0, SHEET_NAME_MAX_LENGTH - suffix.length) + suffix;
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
exports.getSanitisedSheetName = getSanitisedSheetName;
|
|
36
|
+
exports.getUniqueSheetNames = getUniqueSheetNames;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { XlsxCellValue } from "./cell.cjs";
|
|
2
|
+
import { XlsxColumn } from "./column.cjs";
|
|
3
|
+
//#region src/xlsx/sheet.d.ts
|
|
4
|
+
type XlsxSheet = {
|
|
5
|
+
name: string;
|
|
6
|
+
columns: XlsxColumn[];
|
|
7
|
+
data: Record<string, XlsxCellValue>[];
|
|
8
|
+
/**
|
|
9
|
+
* Optional lines written above the table — typically a client name and a
|
|
10
|
+
* reporting period. The first line is bold, the rest are plain, and a blank
|
|
11
|
+
* row separates them from the column headers.
|
|
12
|
+
*/
|
|
13
|
+
heading?: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Coerce a sheet name into something Excel will accept: no []:*?/\ characters,
|
|
17
|
+
* no wrapping apostrophes, at most 31 characters, and never empty.
|
|
18
|
+
*
|
|
19
|
+
* Uniqueness is handled separately, since that needs the whole set.
|
|
20
|
+
*/
|
|
21
|
+
declare const getSanitisedSheetName: (name: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* Sanitise every sheet name and break collisions with _2, _3, … while staying
|
|
24
|
+
* inside the 31 character limit. Excel rejects duplicate names outright, so this
|
|
25
|
+
* cannot be left to chance once sheets are generated from data.
|
|
26
|
+
*/
|
|
27
|
+
declare const getUniqueSheetNames: (sheets: XlsxSheet[]) => string[];
|
|
28
|
+
//#endregion
|
|
29
|
+
export { XlsxSheet, getSanitisedSheetName, getUniqueSheetNames };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { XlsxCellValue } from "./cell.mjs";
|
|
2
|
+
import { XlsxColumn } from "./column.mjs";
|
|
3
|
+
//#region src/xlsx/sheet.d.ts
|
|
4
|
+
type XlsxSheet = {
|
|
5
|
+
name: string;
|
|
6
|
+
columns: XlsxColumn[];
|
|
7
|
+
data: Record<string, XlsxCellValue>[];
|
|
8
|
+
/**
|
|
9
|
+
* Optional lines written above the table — typically a client name and a
|
|
10
|
+
* reporting period. The first line is bold, the rest are plain, and a blank
|
|
11
|
+
* row separates them from the column headers.
|
|
12
|
+
*/
|
|
13
|
+
heading?: string[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Coerce a sheet name into something Excel will accept: no []:*?/\ characters,
|
|
17
|
+
* no wrapping apostrophes, at most 31 characters, and never empty.
|
|
18
|
+
*
|
|
19
|
+
* Uniqueness is handled separately, since that needs the whole set.
|
|
20
|
+
*/
|
|
21
|
+
declare const getSanitisedSheetName: (name: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* Sanitise every sheet name and break collisions with _2, _3, … while staying
|
|
24
|
+
* inside the 31 character limit. Excel rejects duplicate names outright, so this
|
|
25
|
+
* cannot be left to chance once sheets are generated from data.
|
|
26
|
+
*/
|
|
27
|
+
declare const getUniqueSheetNames: (sheets: XlsxSheet[]) => string[];
|
|
28
|
+
//#endregion
|
|
29
|
+
export { XlsxSheet, getSanitisedSheetName, getUniqueSheetNames };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/xlsx/sheet.ts
|
|
2
|
+
/** Excel refuses to open a workbook whose sheet name exceeds 31 characters. */
|
|
3
|
+
const SHEET_NAME_MAX_LENGTH = 31;
|
|
4
|
+
/**
|
|
5
|
+
* Coerce a sheet name into something Excel will accept: no []:*?/\ characters,
|
|
6
|
+
* no wrapping apostrophes, at most 31 characters, and never empty.
|
|
7
|
+
*
|
|
8
|
+
* Uniqueness is handled separately, since that needs the whole set.
|
|
9
|
+
*/
|
|
10
|
+
const getSanitisedSheetName = (name) => {
|
|
11
|
+
const cleaned = (name || "").replace(/[[\]:*?/\\]/g, "_").replace(/^'+|'+$/g, "").trim().slice(0, SHEET_NAME_MAX_LENGTH);
|
|
12
|
+
return "" === cleaned ? "Sheet" : cleaned;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Sanitise every sheet name and break collisions with _2, _3, … while staying
|
|
16
|
+
* inside the 31 character limit. Excel rejects duplicate names outright, so this
|
|
17
|
+
* cannot be left to chance once sheets are generated from data.
|
|
18
|
+
*/
|
|
19
|
+
const getUniqueSheetNames = (sheets) => {
|
|
20
|
+
const used = {};
|
|
21
|
+
return sheets.map((sheet) => {
|
|
22
|
+
const base = getSanitisedSheetName(sheet.name);
|
|
23
|
+
const key = base.toLowerCase();
|
|
24
|
+
if (!(key in used)) {
|
|
25
|
+
used[key] = 1;
|
|
26
|
+
return base;
|
|
27
|
+
}
|
|
28
|
+
used[key] += 1;
|
|
29
|
+
const suffix = `_${used[key]}`;
|
|
30
|
+
return base.slice(0, SHEET_NAME_MAX_LENGTH - suffix.length) + suffix;
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { getSanitisedSheetName, getUniqueSheetNames };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@8ms/helpers",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.24",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/8millionstories-organisation/8ms-helpers-ts.git"
|
|
@@ -11,8 +11,29 @@
|
|
|
11
11
|
"build": "tsdown",
|
|
12
12
|
"jest": "jest --watch"
|
|
13
13
|
},
|
|
14
|
+
"opEnvironmentIds": {
|
|
15
|
+
"global": "mlygwnyazmvvzwfg6tcdpin3hu",
|
|
16
|
+
"shared": "wwhbhlaofhjwnjafli2x4ci3gy",
|
|
17
|
+
"production": "",
|
|
18
|
+
"staging": "",
|
|
19
|
+
"development": ""
|
|
20
|
+
},
|
|
21
|
+
"opWorkloadIds": {
|
|
22
|
+
"global": "RPZNVJDXA5ENXARI74H3Q4KDYY",
|
|
23
|
+
"shared": "UPIH3E7TZ5CM5B754JPUYPXR6Y",
|
|
24
|
+
"production": "",
|
|
25
|
+
"staging": "",
|
|
26
|
+
"development": ""
|
|
27
|
+
},
|
|
28
|
+
"opSkipKeys": [
|
|
29
|
+
"IS_LOCAL",
|
|
30
|
+
"NEXT_IS_LOCAL",
|
|
31
|
+
"OP_SERVICE_ACCOUNT_TOKEN",
|
|
32
|
+
"SERVERLESS_ACCESS_KEY",
|
|
33
|
+
"TZ"
|
|
34
|
+
],
|
|
14
35
|
"dependencies": {
|
|
15
|
-
"fs-extra": "^11.
|
|
36
|
+
"fs-extra": "^11.4.0",
|
|
16
37
|
"ky": "^2.0.2",
|
|
17
38
|
"luxon": "^3.7.2",
|
|
18
39
|
"zod": "^4.4.3"
|
|
@@ -26,16 +47,16 @@
|
|
|
26
47
|
"@aws-sdk/client-glue": "^3.0.0",
|
|
27
48
|
"@aws-sdk/client-lambda": "^3.0.0",
|
|
28
49
|
"@aws-sdk/client-s3": "^3.0.0",
|
|
29
|
-
"@aws-sdk/client-
|
|
50
|
+
"@aws-sdk/client-sesv2": "^3.0.0",
|
|
30
51
|
"@aws-sdk/client-sqs": "^3.0.0",
|
|
31
52
|
"@aws-sdk/client-ssm": "^3.0.0",
|
|
32
53
|
"@aws-sdk/client-sts": "^3.0.0",
|
|
33
54
|
"@aws-sdk/lib-storage": "^3.0.0",
|
|
34
55
|
"@aws-sdk/s3-request-presigner": "^3.0.0",
|
|
35
|
-
"@google-cloud/bigquery": "^
|
|
36
|
-
"@google-cloud/common": "^
|
|
37
|
-
"@google-cloud/storage": "^
|
|
38
|
-
"@googleapis/sheets": "^
|
|
56
|
+
"@google-cloud/bigquery": "^9.0.0",
|
|
57
|
+
"@google-cloud/common": "^8.0.0",
|
|
58
|
+
"@google-cloud/storage": "^8.0.0",
|
|
59
|
+
"@googleapis/sheets": "^14.0.0",
|
|
39
60
|
"@planetscale/database": "^1.0.0",
|
|
40
61
|
"@prisma/adapter-mariadb": "^7.0.0",
|
|
41
62
|
"@prisma/adapter-pg": "^7.0.0",
|
|
@@ -45,13 +66,14 @@
|
|
|
45
66
|
"@vercel/oidc-aws-credentials-provider": "^3.0.0",
|
|
46
67
|
"drizzle-orm": "*",
|
|
47
68
|
"gaxios": "^7.0.0",
|
|
48
|
-
"google-auth-library": "^
|
|
49
|
-
"googleapis-common": "^
|
|
69
|
+
"google-auth-library": "^11.0.0",
|
|
70
|
+
"googleapis-common": "^9.0.0",
|
|
71
|
+
"jszip": "^3.10.1",
|
|
50
72
|
"mysql2": "^3.0.0",
|
|
51
73
|
"next": "^16.0.0",
|
|
52
74
|
"pg": "^8.0.0",
|
|
53
75
|
"react": "^19.0.0",
|
|
54
|
-
"react-intersection-observer": "^
|
|
76
|
+
"react-intersection-observer": "^11.0.0",
|
|
55
77
|
"swr": "^2.0.0"
|
|
56
78
|
},
|
|
57
79
|
"peerDependenciesMeta": {
|
|
@@ -79,7 +101,7 @@
|
|
|
79
101
|
"@aws-sdk/client-s3": {
|
|
80
102
|
"optional": true
|
|
81
103
|
},
|
|
82
|
-
"@aws-sdk/client-
|
|
104
|
+
"@aws-sdk/client-sesv2": {
|
|
83
105
|
"optional": true
|
|
84
106
|
},
|
|
85
107
|
"@aws-sdk/client-sqs": {
|
|
@@ -133,9 +155,6 @@
|
|
|
133
155
|
"drizzle-orm": {
|
|
134
156
|
"optional": true
|
|
135
157
|
},
|
|
136
|
-
"fs-extra": {
|
|
137
|
-
"optional": true
|
|
138
|
-
},
|
|
139
158
|
"gaxios": {
|
|
140
159
|
"optional": true
|
|
141
160
|
},
|
|
@@ -145,6 +164,9 @@
|
|
|
145
164
|
"googleapis-common": {
|
|
146
165
|
"optional": true
|
|
147
166
|
},
|
|
167
|
+
"jszip": {
|
|
168
|
+
"optional": true
|
|
169
|
+
},
|
|
148
170
|
"mysql2": {
|
|
149
171
|
"optional": true
|
|
150
172
|
},
|
|
@@ -162,56 +184,56 @@
|
|
|
162
184
|
}
|
|
163
185
|
},
|
|
164
186
|
"devDependencies": {
|
|
165
|
-
"@1password/sdk": "^0.
|
|
166
|
-
"@aws-sdk/client-cloudwatch": "^3.
|
|
167
|
-
"@aws-sdk/client-cloudwatch-logs": "^3.
|
|
168
|
-
"@aws-sdk/client-ec2": "^3.
|
|
169
|
-
"@aws-sdk/client-ecs": "^3.
|
|
170
|
-
"@aws-sdk/client-glue": "^3.
|
|
171
|
-
"@aws-sdk/client-lambda": "^3.
|
|
172
|
-
"@aws-sdk/client-s3": "^3.
|
|
173
|
-
"@aws-sdk/client-
|
|
174
|
-
"@aws-sdk/client-sqs": "^3.
|
|
175
|
-
"@aws-sdk/client-ssm": "^3.
|
|
176
|
-
"@aws-sdk/client-sts": "^3.
|
|
177
|
-
"@aws-sdk/lib-storage": "^3.
|
|
178
|
-
"@aws-sdk/s3-request-presigner": "^3.
|
|
179
|
-
"@aws-sdk/types": "^3.
|
|
180
|
-
"@babel/core": "^
|
|
181
|
-
"@babel/preset-env": "^
|
|
182
|
-
"@babel/preset-typescript": "^
|
|
183
|
-
"@google-cloud/bigquery": "^
|
|
184
|
-
"@google-cloud/common": "^
|
|
185
|
-
"@google-cloud/storage": "^
|
|
186
|
-
"@googleapis/sheets": "^
|
|
187
|
+
"@1password/sdk": "^0.5.0",
|
|
188
|
+
"@aws-sdk/client-cloudwatch": "^3.1116.0",
|
|
189
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.1116.0",
|
|
190
|
+
"@aws-sdk/client-ec2": "^3.1116.0",
|
|
191
|
+
"@aws-sdk/client-ecs": "^3.1116.0",
|
|
192
|
+
"@aws-sdk/client-glue": "^3.1116.0",
|
|
193
|
+
"@aws-sdk/client-lambda": "^3.1116.0",
|
|
194
|
+
"@aws-sdk/client-s3": "^3.1116.0",
|
|
195
|
+
"@aws-sdk/client-sesv2": "^3.1116.0",
|
|
196
|
+
"@aws-sdk/client-sqs": "^3.1116.0",
|
|
197
|
+
"@aws-sdk/client-ssm": "^3.1116.0",
|
|
198
|
+
"@aws-sdk/client-sts": "^3.1116.0",
|
|
199
|
+
"@aws-sdk/lib-storage": "^3.1116.0",
|
|
200
|
+
"@aws-sdk/s3-request-presigner": "^3.1116.0",
|
|
201
|
+
"@aws-sdk/types": "^3.974.5",
|
|
202
|
+
"@babel/core": "^7.29.7",
|
|
203
|
+
"@babel/preset-env": "^7.29.7",
|
|
204
|
+
"@babel/preset-typescript": "^7.29.7",
|
|
205
|
+
"@google-cloud/bigquery": "^9.0.2",
|
|
206
|
+
"@google-cloud/common": "^8.0.1",
|
|
207
|
+
"@google-cloud/storage": "^8.0.1",
|
|
208
|
+
"@googleapis/sheets": "^14.0.0",
|
|
187
209
|
"@planetscale/database": "^1.20.1",
|
|
188
|
-
"@prisma/adapter-mariadb": "^7.
|
|
189
|
-
"@prisma/adapter-pg": "^7.
|
|
190
|
-
"@prisma/adapter-planetscale": "^7.
|
|
191
|
-
"@prisma/client": "^7.
|
|
210
|
+
"@prisma/adapter-mariadb": "^7.9.1",
|
|
211
|
+
"@prisma/adapter-pg": "^7.9.1",
|
|
212
|
+
"@prisma/adapter-planetscale": "^7.9.1",
|
|
213
|
+
"@prisma/client": "^7.9.1",
|
|
192
214
|
"@types/fs-extra": "^11.0.4",
|
|
193
|
-
"@types/jest": "30.0.0",
|
|
194
|
-
"@types/luxon": "3.7.
|
|
195
|
-
"@types/node": "^24.13.
|
|
196
|
-
"@types/react": "^19.2.
|
|
197
|
-
"@vercel/oidc": "^3.
|
|
198
|
-
"@vercel/oidc-aws-credentials-provider": "^3.
|
|
215
|
+
"@types/jest": "^30.0.0",
|
|
216
|
+
"@types/luxon": "^3.7.5",
|
|
217
|
+
"@types/node": "^24.13.3",
|
|
218
|
+
"@types/react": "^19.2.18",
|
|
219
|
+
"@vercel/oidc": "^3.8.5",
|
|
220
|
+
"@vercel/oidc-aws-credentials-provider": "^3.3.5",
|
|
199
221
|
"babel-jest": "30.4.1",
|
|
200
222
|
"dotenv": "^17.4.2",
|
|
201
223
|
"drizzle-orm": "beta",
|
|
202
|
-
"
|
|
203
|
-
"
|
|
204
|
-
"
|
|
205
|
-
"googleapis-common": "^8.0.2",
|
|
224
|
+
"gaxios": "^7.3.1",
|
|
225
|
+
"google-auth-library": "^11.0.2",
|
|
226
|
+
"googleapis-common": "^9.0.3",
|
|
206
227
|
"jest": "^30.4.2",
|
|
207
|
-
"
|
|
208
|
-
"
|
|
209
|
-
"
|
|
210
|
-
"
|
|
211
|
-
"react
|
|
212
|
-
"
|
|
228
|
+
"jszip": "^3.10.1",
|
|
229
|
+
"mysql2": "^3.24.1",
|
|
230
|
+
"next": "^16.3.2",
|
|
231
|
+
"pg": "^8.23.0",
|
|
232
|
+
"react": "^19.2.8",
|
|
233
|
+
"react-intersection-observer": "^11.0.0",
|
|
234
|
+
"swr": "^2.5.1",
|
|
213
235
|
"ts-node": "^10.9.2",
|
|
214
|
-
"tsdown": "^0.22.
|
|
236
|
+
"tsdown": "^0.22.14",
|
|
215
237
|
"tslib": "^2.8.1",
|
|
216
238
|
"typescript": "^6.0.3"
|
|
217
239
|
},
|
|
@@ -1200,6 +1222,30 @@
|
|
|
1200
1222
|
"import": "./dist/webWorker/webWorkerState.mjs",
|
|
1201
1223
|
"require": "./dist/webWorker/webWorkerState.cjs"
|
|
1202
1224
|
},
|
|
1225
|
+
"./xlsx": {
|
|
1226
|
+
"import": "./dist/xlsx/index.mjs",
|
|
1227
|
+
"require": "./dist/xlsx/index.cjs"
|
|
1228
|
+
},
|
|
1229
|
+
"./xlsx/cell": {
|
|
1230
|
+
"import": "./dist/xlsx/cell.mjs",
|
|
1231
|
+
"require": "./dist/xlsx/cell.cjs"
|
|
1232
|
+
},
|
|
1233
|
+
"./xlsx/column": {
|
|
1234
|
+
"import": "./dist/xlsx/column.mjs",
|
|
1235
|
+
"require": "./dist/xlsx/column.cjs"
|
|
1236
|
+
},
|
|
1237
|
+
"./xlsx/createXlsx": {
|
|
1238
|
+
"import": "./dist/xlsx/createXlsx.mjs",
|
|
1239
|
+
"require": "./dist/xlsx/createXlsx.cjs"
|
|
1240
|
+
},
|
|
1241
|
+
"./xlsx/modifyXlsx": {
|
|
1242
|
+
"import": "./dist/xlsx/modifyXlsx.mjs",
|
|
1243
|
+
"require": "./dist/xlsx/modifyXlsx.cjs"
|
|
1244
|
+
},
|
|
1245
|
+
"./xlsx/sheet": {
|
|
1246
|
+
"import": "./dist/xlsx/sheet.mjs",
|
|
1247
|
+
"require": "./dist/xlsx/sheet.cjs"
|
|
1248
|
+
},
|
|
1203
1249
|
"./xml/server": {
|
|
1204
1250
|
"import": "./dist/xml/server/index.mjs",
|
|
1205
1251
|
"require": "./dist/xml/server/index.cjs"
|