reamkit 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/esm/bidi/algorithm.d.ts +9 -0
- package/dist/esm/bidi/algorithm.js +458 -0
- package/dist/esm/bidi/char-types.d.ts +2 -0
- package/dist/esm/bidi/char-types.js +439 -0
- package/dist/esm/bidi/index.d.ts +14 -0
- package/dist/esm/bidi/index.js +25 -0
- package/dist/esm/converter/docx-to-pdf.d.ts +15 -0
- package/dist/esm/converter/docx-to-pdf.js +227 -0
- package/dist/esm/converter/index.d.ts +4 -0
- package/dist/esm/converter/index.js +2 -0
- package/dist/esm/converter/xlsx-to-pdf.d.ts +13 -0
- package/dist/esm/converter/xlsx-to-pdf.js +515 -0
- package/dist/esm/crypto/asn1.d.ts +23 -0
- package/dist/esm/crypto/asn1.js +123 -0
- package/dist/esm/crypto/cms.d.ts +9 -0
- package/dist/esm/crypto/cms.js +34 -0
- package/dist/esm/crypto/index.d.ts +2 -0
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/document-model/index.d.ts +1 -0
- package/dist/esm/document-model/index.js +0 -0
- package/dist/esm/document-model/types.d.ts +403 -0
- package/dist/esm/font/arabic-joining.d.ts +4 -0
- package/dist/esm/font/arabic-joining.js +97 -0
- package/dist/esm/font/binary-reader.d.ts +13 -0
- package/dist/esm/font/binary-reader.js +44 -0
- package/dist/esm/font/font-registry.d.ts +19 -0
- package/dist/esm/font/font-registry.js +39 -0
- package/dist/esm/font/index.d.ts +7 -0
- package/dist/esm/font/opentype-layout.d.ts +21 -0
- package/dist/esm/font/opentype-layout.js +329 -0
- package/dist/esm/font/ttf-parser.d.ts +29 -0
- package/dist/esm/font/ttf-parser.js +290 -0
- package/dist/esm/font/ttf-subset.d.ts +3 -0
- package/dist/esm/font/ttf-subset.js +201 -0
- package/dist/esm/fonts/index.d.ts +2 -0
- package/dist/esm/fonts/remote-fonts.d.ts +13 -0
- package/dist/esm/fonts/remote-fonts.js +94 -0
- package/dist/esm/hyphenation/index.d.ts +10 -0
- package/dist/esm/hyphenation/index.js +38 -0
- package/dist/esm/hyphenation/liang.d.ts +10 -0
- package/dist/esm/hyphenation/liang.js +79 -0
- package/dist/esm/hyphenation/patterns-en-us.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-en-us.js +5 -0
- package/dist/esm/hyphenation/patterns-ru.d.ts +2 -0
- package/dist/esm/hyphenation/patterns-ru.js +5 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +13 -0
- package/dist/esm/line-breaker/index.d.ts +2 -0
- package/dist/esm/line-breaker/knuth-plass.d.ts +30 -0
- package/dist/esm/line-breaker/knuth-plass.js +172 -0
- package/dist/esm/numbering/index.d.ts +1 -0
- package/dist/esm/numbering/state.d.ts +6 -0
- package/dist/esm/numbering/state.js +83 -0
- package/dist/esm/ooxml/drawingml/chart-parser.d.ts +3 -0
- package/dist/esm/ooxml/drawingml/chart-parser.js +218 -0
- package/dist/esm/ooxml/drawingml/colors.d.ts +17 -0
- package/dist/esm/ooxml/drawingml/colors.js +125 -0
- package/dist/esm/ooxml/drawingml/theme-parser.d.ts +1 -0
- package/dist/esm/ooxml/drawingml/theme-parser.js +55 -0
- package/dist/esm/ooxml/index.d.ts +1 -0
- package/dist/esm/ooxml/math/omml-parser.d.ts +4 -0
- package/dist/esm/ooxml/math/omml-parser.js +217 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.d.ts +6 -0
- package/dist/esm/ooxml/spreadsheet/cell-reference.js +26 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.d.ts +11 -0
- package/dist/esm/ooxml/spreadsheet/defined-name-ref.js +64 -0
- package/dist/esm/ooxml/spreadsheet/index.d.ts +12 -0
- package/dist/esm/ooxml/spreadsheet/index.js +7 -0
- package/dist/esm/ooxml/spreadsheet/number-format.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/number-format.js +438 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.d.ts +1 -0
- package/dist/esm/ooxml/spreadsheet/shared-strings-parser.js +47 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.d.ts +52 -0
- package/dist/esm/ooxml/spreadsheet/styles-parser.js +225 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.d.ts +16 -0
- package/dist/esm/ooxml/spreadsheet/workbook-parser.js +90 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.d.ts +60 -0
- package/dist/esm/ooxml/spreadsheet/worksheet-parser.js +311 -0
- package/dist/esm/ooxml/wordproc/document-parser.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/document-parser.js +274 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.d.ts +33 -0
- package/dist/esm/ooxml/wordproc/drawing-parser.js +374 -0
- package/dist/esm/ooxml/wordproc/font-table.d.ts +15 -0
- package/dist/esm/ooxml/wordproc/font-table.js +82 -0
- package/dist/esm/ooxml/wordproc/index.d.ts +10 -0
- package/dist/esm/ooxml/wordproc/index.js +9 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/numbering-parser.js +89 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/paragraph-properties.js +85 -0
- package/dist/esm/ooxml/wordproc/po-helpers.d.ts +14 -0
- package/dist/esm/ooxml/wordproc/po-helpers.js +76 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/po-to-flat.js +28 -0
- package/dist/esm/ooxml/wordproc/run-properties.d.ts +2 -0
- package/dist/esm/ooxml/wordproc/run-properties.js +82 -0
- package/dist/esm/ooxml/wordproc/settings-parser.d.ts +5 -0
- package/dist/esm/ooxml/wordproc/settings-parser.js +26 -0
- package/dist/esm/ooxml/wordproc/styles-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/styles-parser.js +67 -0
- package/dist/esm/ooxml/wordproc/table-parser.d.ts +3 -0
- package/dist/esm/ooxml/wordproc/table-parser.js +162 -0
- package/dist/esm/ooxml/wordproc/text-extractor.d.ts +1 -0
- package/dist/esm/ooxml/wordproc/text-extractor.js +1 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.d.ts +9 -0
- package/dist/esm/ooxml/wordproc/xml-helpers.js +36 -0
- package/dist/esm/opc/core-properties.d.ts +11 -0
- package/dist/esm/opc/core-properties.js +51 -0
- package/dist/esm/opc/index.d.ts +5 -0
- package/dist/esm/opc/index.js +3 -0
- package/dist/esm/opc/package.d.ts +26 -0
- package/dist/esm/opc/package.js +113 -0
- package/dist/esm/opc/relationship-types.d.ts +3 -0
- package/dist/esm/opc/relationship-types.js +4 -0
- package/dist/esm/opc/relationships.d.ts +7 -0
- package/dist/esm/opc/relationships.js +28 -0
- package/dist/esm/pdf/arc-to-bezier.d.ts +5 -0
- package/dist/esm/pdf/arc-to-bezier.js +58 -0
- package/dist/esm/pdf/builtin-fonts.d.ts +2 -0
- package/dist/esm/pdf/chart-geometry.d.ts +64 -0
- package/dist/esm/pdf/chart-geometry.js +674 -0
- package/dist/esm/pdf/cid-font.d.ts +15 -0
- package/dist/esm/pdf/cid-font.js +174 -0
- package/dist/esm/pdf/embedded-file.d.ts +11 -0
- package/dist/esm/pdf/embedded-file.js +23 -0
- package/dist/esm/pdf/icc-profile.d.ts +1 -0
- package/dist/esm/pdf/icc-profile.js +166 -0
- package/dist/esm/pdf/image-xobject.d.ts +13 -0
- package/dist/esm/pdf/image-xobject.js +335 -0
- package/dist/esm/pdf/index.d.ts +11 -0
- package/dist/esm/pdf/index.js +5 -0
- package/dist/esm/pdf/math-layout.d.ts +45 -0
- package/dist/esm/pdf/math-layout.js +1138 -0
- package/dist/esm/pdf/objects.d.ts +32 -0
- package/dist/esm/pdf/objects.js +54 -0
- package/dist/esm/pdf/preset-geometry.d.ts +6 -0
- package/dist/esm/pdf/preset-geometry.js +199 -0
- package/dist/esm/pdf/serialize.d.ts +3 -0
- package/dist/esm/pdf/serialize.js +54 -0
- package/dist/esm/pdf/signature.d.ts +25 -0
- package/dist/esm/pdf/signature.js +126 -0
- package/dist/esm/pdf/struct-tree.d.ts +31 -0
- package/dist/esm/pdf/struct-tree.js +109 -0
- package/dist/esm/pdf/styled-page-renderer.d.ts +43 -0
- package/dist/esm/pdf/styled-page-renderer.js +2317 -0
- package/dist/esm/pdf/text-encoding.d.ts +2 -0
- package/dist/esm/pdf/text-page-renderer.d.ts +16 -0
- package/dist/esm/pdf/text-page-renderer.js +4 -0
- package/dist/esm/pdf/vector-graphics.d.ts +46 -0
- package/dist/esm/pdf/vector-graphics.js +103 -0
- package/dist/esm/pdf/writer.d.ts +10 -0
- package/dist/esm/pdf/writer.js +81 -0
- package/dist/esm/pdf/xmp.d.ts +13 -0
- package/dist/esm/pdf/xmp.js +38 -0
- package/dist/esm/style-cascade/index.d.ts +3 -0
- package/dist/esm/style-cascade/resolver.d.ts +4 -0
- package/dist/esm/style-cascade/resolver.js +96 -0
- package/dist/esm/style-cascade/types.d.ts +29 -0
- package/dist/esm/style-cascade/types.js +26 -0
- package/package.json +90 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FontBytesByVariant } from '../font/index.js';
|
|
2
|
+
import { FetchLike } from '../fonts/index.js';
|
|
3
|
+
import { SignatureOptions, StyledRenderOptions } from '../pdf/index.js';
|
|
4
|
+
export interface ConvertXlsxOptions extends Omit<StyledRenderOptions, 'registry' | 'styles'> {
|
|
5
|
+
readonly fontBytes?: Uint8Array;
|
|
6
|
+
readonly fonts?: FontBytesByVariant;
|
|
7
|
+
readonly fontFamily?: string;
|
|
8
|
+
readonly fontFetch?: FetchLike;
|
|
9
|
+
readonly embedSource?: boolean;
|
|
10
|
+
readonly signature?: SignatureOptions;
|
|
11
|
+
}
|
|
12
|
+
export declare function convertXlsxToPdf(xlsx: Uint8Array, options?: ConvertXlsxOptions): Promise<Uint8Array>;
|
|
13
|
+
export declare function convertXlsxToPdfSync(xlsx: Uint8Array, options: ConvertXlsxOptions): Uint8Array;
|
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { FontRegistry } from "../font/font-registry.js";
|
|
2
|
+
import { fetchFontSet } from "../fonts/remote-fonts.js";
|
|
3
|
+
import { OpcPackage } from "../opc/package.js";
|
|
4
|
+
import { parseCoreProperties } from "../opc/core-properties.js";
|
|
5
|
+
import "../opc/index.js";
|
|
6
|
+
import { EMPTY_STYLE_SHEET } from "../ooxml/wordproc/styles-parser.js";
|
|
7
|
+
import "../ooxml/wordproc/index.js";
|
|
8
|
+
import { signPdf } from "../pdf/signature.js";
|
|
9
|
+
import { renderStyledPdf } from "../pdf/styled-page-renderer.js";
|
|
10
|
+
import "../pdf/index.js";
|
|
11
|
+
import { parseAreaRef, parseTitleRowRange } from "../ooxml/spreadsheet/defined-name-ref.js";
|
|
12
|
+
import { parseSharedStrings } from "../ooxml/spreadsheet/shared-strings-parser.js";
|
|
13
|
+
import { parseWorkbook } from "../ooxml/spreadsheet/workbook-parser.js";
|
|
14
|
+
import { parseWorksheet } from "../ooxml/spreadsheet/worksheet-parser.js";
|
|
15
|
+
import { EMPTY_XLSX_STYLES, parseXlsxStyles } from "../ooxml/spreadsheet/styles-parser.js";
|
|
16
|
+
import { applyNumberFormat } from "../ooxml/spreadsheet/number-format.js";
|
|
17
|
+
import "../ooxml/spreadsheet/index.js";
|
|
18
|
+
//#region src/converter/xlsx-to-pdf.ts
|
|
19
|
+
var WORKBOOK_PART = "xl/workbook.xml";
|
|
20
|
+
var SHARED_STRINGS_PART = "xl/sharedStrings.xml";
|
|
21
|
+
var STYLES_PART = "xl/styles.xml";
|
|
22
|
+
var CORE_PROPS_PART = "docProps/core.xml";
|
|
23
|
+
var TWIPS_PER_EXCEL_CHAR = 105;
|
|
24
|
+
var DEFAULT_COL_TWIPS = 960;
|
|
25
|
+
var DEFAULT_ROW_TWIPS = 300;
|
|
26
|
+
var TWIPS_PER_POINT = 20;
|
|
27
|
+
var TWIPS_PER_INCH = 1440;
|
|
28
|
+
var PAPER_SIZES_TWIPS = new Map([
|
|
29
|
+
[1, [12240, 15840]],
|
|
30
|
+
[3, [15840, 24480]],
|
|
31
|
+
[5, [12240, 20160]],
|
|
32
|
+
[8, [16838, 23811]],
|
|
33
|
+
[9, [11906, 16838]],
|
|
34
|
+
[11, [8392, 11906]],
|
|
35
|
+
[70, [5953, 8392]]
|
|
36
|
+
]);
|
|
37
|
+
var DEFAULT_PAPER_TWIPS = [11906, 16838];
|
|
38
|
+
async function convertXlsxToPdf(xlsx, options = {}) {
|
|
39
|
+
const { signature } = options;
|
|
40
|
+
const renderOptions = signature ? {
|
|
41
|
+
...options,
|
|
42
|
+
signaturePlaceholder: signature
|
|
43
|
+
} : options;
|
|
44
|
+
let pdf;
|
|
45
|
+
if (renderOptions.fonts ?? renderOptions.fontBytes) pdf = convertXlsxToPdfSync(xlsx, renderOptions);
|
|
46
|
+
else {
|
|
47
|
+
const fonts = await fetchFontSet({
|
|
48
|
+
...options.fontFamily ? { family: options.fontFamily } : {},
|
|
49
|
+
...options.fontFetch ? { fetch: options.fontFetch } : {}
|
|
50
|
+
});
|
|
51
|
+
pdf = convertXlsxToPdfSync(xlsx, {
|
|
52
|
+
...renderOptions,
|
|
53
|
+
fonts
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return signature ? signPdf(pdf, signature) : pdf;
|
|
57
|
+
}
|
|
58
|
+
function convertXlsxToPdfSync(xlsx, options) {
|
|
59
|
+
const fonts = options.fonts ?? (options.fontBytes ? { regular: options.fontBytes } : void 0);
|
|
60
|
+
if (!fonts) throw new Error("convertXlsxToPdfSync requires options.fonts or options.fontBytes");
|
|
61
|
+
const registry = FontRegistry.fromBytes(fonts);
|
|
62
|
+
const pkg = OpcPackage.open(xlsx);
|
|
63
|
+
const workbookData = pkg.getPart(WORKBOOK_PART);
|
|
64
|
+
if (!workbookData) throw new Error("Not a valid xlsx: missing xl/workbook.xml");
|
|
65
|
+
const { sheets, date1904, definedNames } = parseWorkbook(workbookData);
|
|
66
|
+
if (sheets.length === 0) throw new Error("xlsx has no sheets");
|
|
67
|
+
const sharedStringsData = pkg.getPart(SHARED_STRINGS_PART);
|
|
68
|
+
const sharedStrings = sharedStringsData ? parseSharedStrings(sharedStringsData) : [];
|
|
69
|
+
const stylesData = pkg.getPart(STYLES_PART);
|
|
70
|
+
const styles = stylesData ? parseXlsxStyles(stylesData) : EMPTY_XLSX_STYLES;
|
|
71
|
+
const workbookRels = pkg.getPartRelationships(WORKBOOK_PART);
|
|
72
|
+
const body = [];
|
|
73
|
+
let firstSheetSection;
|
|
74
|
+
for (let sheetIdx = 0; sheetIdx < sheets.length; sheetIdx++) {
|
|
75
|
+
const sheet = sheets[sheetIdx];
|
|
76
|
+
const sheetRel = workbookRels.find((r) => r.id === sheet.relationshipId);
|
|
77
|
+
if (!sheetRel) continue;
|
|
78
|
+
const resolved = pkg.resolveRelatedPart(WORKBOOK_PART, sheetRel);
|
|
79
|
+
if (!resolved) continue;
|
|
80
|
+
const worksheet = parseWorksheet(resolved.data);
|
|
81
|
+
if (sheetIdx === 0) firstSheetSection = sectionFromWorksheet(worksheet);
|
|
82
|
+
if (sheetIdx > 0) body.push({
|
|
83
|
+
kind: "paragraph",
|
|
84
|
+
paragraph: {
|
|
85
|
+
properties: { pageBreakBefore: true },
|
|
86
|
+
runs: []
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const printArea = resolvePrintArea(definedNames, sheetIdx);
|
|
90
|
+
const titleRows = resolvePrintTitleRows(definedNames, sheetIdx);
|
|
91
|
+
const gridLines = worksheet.printOptions?.gridLines === true;
|
|
92
|
+
body.push(...worksheetToBody(worksheet, sharedStrings, styles, date1904, {
|
|
93
|
+
...printArea ? { printArea } : {},
|
|
94
|
+
...titleRows ? { titleRows } : {},
|
|
95
|
+
gridLines
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
const coreData = pkg.getPart(CORE_PROPS_PART);
|
|
99
|
+
const coreProps = coreData ? parseCoreProperties(coreData) : void 0;
|
|
100
|
+
const { fontBytes: _ignoreA, fonts: _ignoreB, section: sectionOverride, info: callerInfo, embedSource, attachments: callerAttachments, signature: _ignoreSig, ...renderOptions } = options;
|
|
101
|
+
const section = sectionOverride ?? firstSheetSection;
|
|
102
|
+
const info = mergeInfo(coreProps, callerInfo);
|
|
103
|
+
const attachments = [...callerAttachments ?? []];
|
|
104
|
+
if (embedSource && options.pdfA?.startsWith("PDF/A-3")) attachments.push({
|
|
105
|
+
name: "source.xlsx",
|
|
106
|
+
bytes: xlsx,
|
|
107
|
+
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
108
|
+
relationship: "Source",
|
|
109
|
+
description: "Source Excel workbook"
|
|
110
|
+
});
|
|
111
|
+
return renderStyledPdf(body, {
|
|
112
|
+
registry,
|
|
113
|
+
styles: EMPTY_STYLE_SHEET,
|
|
114
|
+
...section ? { section } : {},
|
|
115
|
+
...info ? { info } : {},
|
|
116
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
117
|
+
...renderOptions
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function mergeInfo(core, caller) {
|
|
121
|
+
if (!core && !caller) return void 0;
|
|
122
|
+
return {
|
|
123
|
+
...core?.title ? { title: core.title } : {},
|
|
124
|
+
...core?.creator ? { author: core.creator } : {},
|
|
125
|
+
...core?.subject ? { subject: core.subject } : {},
|
|
126
|
+
...core?.keywords ? { keywords: core.keywords } : {},
|
|
127
|
+
...core?.created ? { creationDate: core.created } : {},
|
|
128
|
+
...core?.modified ? { modificationDate: core.modified } : {},
|
|
129
|
+
...caller
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function sectionFromWorksheet(worksheet) {
|
|
133
|
+
const pageSize = pageSizeFromSetup(worksheet.pageSetup);
|
|
134
|
+
const margins = marginsFromXlsx(worksheet.pageMargins);
|
|
135
|
+
if (!pageSize && !margins) return void 0;
|
|
136
|
+
return {
|
|
137
|
+
...pageSize ? { pageSize } : {},
|
|
138
|
+
...margins ? { margins } : {},
|
|
139
|
+
headers: [],
|
|
140
|
+
footers: []
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function pageSizeFromSetup(setup) {
|
|
144
|
+
if (!setup) return void 0;
|
|
145
|
+
const paper = setup.paperSize !== void 0 ? PAPER_SIZES_TWIPS.get(setup.paperSize) ?? DEFAULT_PAPER_TWIPS : DEFAULT_PAPER_TWIPS;
|
|
146
|
+
const [w, h] = setup.orientation === "landscape" ? [paper[1], paper[0]] : paper;
|
|
147
|
+
const orientation = setup.orientation === "landscape" ? "landscape" : "portrait";
|
|
148
|
+
if (setup.paperSize === void 0 && setup.orientation !== "landscape") return void 0;
|
|
149
|
+
return {
|
|
150
|
+
widthTwips: w,
|
|
151
|
+
heightTwips: h,
|
|
152
|
+
orientation
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function marginsFromXlsx(margins) {
|
|
156
|
+
if (!margins) return void 0;
|
|
157
|
+
return {
|
|
158
|
+
topTwips: Math.round(margins.topInches * TWIPS_PER_INCH),
|
|
159
|
+
rightTwips: Math.round(margins.rightInches * TWIPS_PER_INCH),
|
|
160
|
+
bottomTwips: Math.round(margins.bottomInches * TWIPS_PER_INCH),
|
|
161
|
+
leftTwips: Math.round(margins.leftInches * TWIPS_PER_INCH),
|
|
162
|
+
...margins.headerInches !== void 0 ? { headerTwips: Math.round(margins.headerInches * TWIPS_PER_INCH) } : {},
|
|
163
|
+
...margins.footerInches !== void 0 ? { footerTwips: Math.round(margins.footerInches * TWIPS_PER_INCH) } : {}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
var PRINT_AREA_NAME = "_xlnm.Print_Area";
|
|
167
|
+
var PRINT_TITLES_NAME = "_xlnm.Print_Titles";
|
|
168
|
+
function resolvePrintArea(definedNames, sheetIdx) {
|
|
169
|
+
for (const dn of definedNames) if (dn.name === PRINT_AREA_NAME && dn.localSheetId === sheetIdx) return parseAreaRef(dn.value);
|
|
170
|
+
}
|
|
171
|
+
function resolvePrintTitleRows(definedNames, sheetIdx) {
|
|
172
|
+
for (const dn of definedNames) if (dn.name === PRINT_TITLES_NAME && dn.localSheetId === sheetIdx) return parseTitleRowRange(dn.value);
|
|
173
|
+
}
|
|
174
|
+
var MIN_PRINT_SCALE = .1;
|
|
175
|
+
function sheetContentWidthTwips(worksheet) {
|
|
176
|
+
const pageWidthTwips = pageSizeFromSetup(worksheet.pageSetup)?.widthTwips ?? DEFAULT_PAPER_TWIPS[0];
|
|
177
|
+
const margins = marginsFromXlsx(worksheet.pageMargins);
|
|
178
|
+
const left = margins?.leftTwips ?? TWIPS_PER_INCH;
|
|
179
|
+
const right = margins?.rightTwips ?? TWIPS_PER_INCH;
|
|
180
|
+
return Math.max(TWIPS_PER_INCH / 2, pageWidthTwips - left - right);
|
|
181
|
+
}
|
|
182
|
+
function sheetContentHeightTwips(worksheet) {
|
|
183
|
+
const pageHeightTwips = pageSizeFromSetup(worksheet.pageSetup)?.heightTwips ?? DEFAULT_PAPER_TWIPS[1];
|
|
184
|
+
const margins = marginsFromXlsx(worksheet.pageMargins);
|
|
185
|
+
const top = margins?.topTwips ?? TWIPS_PER_INCH;
|
|
186
|
+
const bottom = margins?.bottomTwips ?? TWIPS_PER_INCH;
|
|
187
|
+
return Math.max(TWIPS_PER_INCH / 2, pageHeightTwips - top - bottom);
|
|
188
|
+
}
|
|
189
|
+
function computePrintScale(worksheet, totalGridTwips, contentWidthTwips, totalGridHeightTwips, contentHeightTwips) {
|
|
190
|
+
const setup = worksheet.pageSetup;
|
|
191
|
+
let s = 1;
|
|
192
|
+
if (worksheet.fitToPage) {
|
|
193
|
+
const fitW = setup?.fitToWidth ?? 1;
|
|
194
|
+
let sW = 1;
|
|
195
|
+
let sH = 1;
|
|
196
|
+
if (fitW >= 1 && totalGridTwips > 0) sW = contentWidthTwips * fitW / totalGridTwips;
|
|
197
|
+
const fitH = setup?.fitToHeight;
|
|
198
|
+
if (fitH !== void 0 && fitH >= 1 && totalGridHeightTwips > 0) sH = contentHeightTwips * fitH / totalGridHeightTwips;
|
|
199
|
+
s = Math.min(sW, sH);
|
|
200
|
+
} else if (setup?.scale !== void 0 && setup.scale > 0) s = setup.scale / 100;
|
|
201
|
+
return Math.min(1, Math.max(MIN_PRINT_SCALE, s));
|
|
202
|
+
}
|
|
203
|
+
function scaleRunFont(props, scale) {
|
|
204
|
+
const hp = props.fontSizeHalfPoints ?? 22;
|
|
205
|
+
return {
|
|
206
|
+
...props,
|
|
207
|
+
fontSizeHalfPoints: Math.max(2, Math.round(hp * scale))
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
var MAX_SHEET_TEXT_CHARS = 1e6;
|
|
211
|
+
function worksheetToBody(worksheet, sharedStrings, styles, date1904, print) {
|
|
212
|
+
if (worksheet.maxRow < 0 || worksheet.maxColumn < 0) return [];
|
|
213
|
+
let usedRow = -1;
|
|
214
|
+
let usedCol = -1;
|
|
215
|
+
for (const c of worksheet.cells) if (c.rawValue !== "" || c.inlineText !== void 0) {
|
|
216
|
+
if (c.row > usedRow) usedRow = c.row;
|
|
217
|
+
if (c.column > usedCol) usedCol = c.column;
|
|
218
|
+
}
|
|
219
|
+
for (const m of worksheet.merges) {
|
|
220
|
+
if (m.endRow > usedRow) usedRow = m.endRow;
|
|
221
|
+
if (m.endColumn > usedCol) usedCol = m.endColumn;
|
|
222
|
+
}
|
|
223
|
+
if (usedRow < 0 || usedCol < 0) return [];
|
|
224
|
+
let rowStart = 0;
|
|
225
|
+
let colStart = 0;
|
|
226
|
+
let rowEnd = usedRow;
|
|
227
|
+
let colEnd = usedCol;
|
|
228
|
+
if (print.printArea) {
|
|
229
|
+
rowStart = Math.max(0, print.printArea.startRow);
|
|
230
|
+
colStart = Math.max(0, print.printArea.startColumn);
|
|
231
|
+
rowEnd = Math.min(usedRow, print.printArea.endRow);
|
|
232
|
+
colEnd = Math.min(usedCol, print.printArea.endColumn);
|
|
233
|
+
}
|
|
234
|
+
if (rowEnd < rowStart || colEnd < colStart) return [];
|
|
235
|
+
const MAX_GRID_COLS = 1024;
|
|
236
|
+
const rowCount = Math.min(rowEnd - rowStart + 1, 5e4);
|
|
237
|
+
const colCount = Math.min(colEnd - colStart + 1, MAX_GRID_COLS);
|
|
238
|
+
const rowWindowEnd = rowStart + rowCount - 1;
|
|
239
|
+
const colWindowEnd = colStart + colCount - 1;
|
|
240
|
+
const rowHeightMap = /* @__PURE__ */ new Map();
|
|
241
|
+
for (const h of worksheet.rowHeights) {
|
|
242
|
+
const local = h.row - rowStart;
|
|
243
|
+
if (local < 0 || local >= rowCount) continue;
|
|
244
|
+
const heightTwips = Math.round(h.heightPt * TWIPS_PER_POINT);
|
|
245
|
+
rowHeightMap.set(local, {
|
|
246
|
+
heightTwips,
|
|
247
|
+
heightRule: "atLeast"
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
const cellMatrix = Array.from({ length: rowCount }, () => new Array(colCount));
|
|
251
|
+
for (const cell of worksheet.cells) {
|
|
252
|
+
const lr = cell.row - rowStart;
|
|
253
|
+
const lc = cell.column - colStart;
|
|
254
|
+
if (lr >= 0 && lr < rowCount && lc >= 0 && lc < colCount) cellMatrix[lr][lc] = cell;
|
|
255
|
+
}
|
|
256
|
+
const mergeOrigins = /* @__PURE__ */ new Map();
|
|
257
|
+
const insideMerge = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const m of worksheet.merges) {
|
|
259
|
+
if (m.endRow < rowStart || m.startRow > rowWindowEnd) continue;
|
|
260
|
+
if (m.endColumn < colStart || m.startColumn > colWindowEnd) continue;
|
|
261
|
+
mergeOrigins.set(key(m.startRow, m.startColumn), m);
|
|
262
|
+
const rEnd = Math.min(m.endRow, rowWindowEnd);
|
|
263
|
+
const cEnd = Math.min(m.endColumn, colWindowEnd);
|
|
264
|
+
for (let r = Math.max(m.startRow, rowStart); r <= rEnd; r++) for (let c = Math.max(m.startColumn, colStart); c <= cEnd; c++) if (!(r === m.startRow && c === m.startColumn)) insideMerge.add(key(r, c));
|
|
265
|
+
}
|
|
266
|
+
const columnWidths = new Array(colCount).fill(DEFAULT_COL_TWIPS);
|
|
267
|
+
for (const col of worksheet.columns) {
|
|
268
|
+
const twips = Math.round(col.widthChars * TWIPS_PER_EXCEL_CHAR);
|
|
269
|
+
for (let abs = col.min - 1; abs <= col.max - 1; abs++) {
|
|
270
|
+
const i = abs - colStart;
|
|
271
|
+
if (i >= 0 && i < colCount) columnWidths[i] = twips;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const totalGridTwips = columnWidths.reduce((sum, w) => sum + w, 0);
|
|
275
|
+
let totalGridHeightTwips = 0;
|
|
276
|
+
for (let r = 0; r < rowCount; r++) totalGridHeightTwips += rowHeightMap.get(r)?.heightTwips ?? DEFAULT_ROW_TWIPS;
|
|
277
|
+
const printScale = computePrintScale(worksheet, totalGridTwips, sheetContentWidthTwips(worksheet), totalGridHeightTwips, sheetContentHeightTwips(worksheet));
|
|
278
|
+
const scaled = printScale < .999;
|
|
279
|
+
const breakRows = new Set(worksheet.rowBreaks ?? []);
|
|
280
|
+
let textBudget = MAX_SHEET_TEXT_CHARS;
|
|
281
|
+
const rows = [];
|
|
282
|
+
for (let r = 0; r < rowCount; r++) {
|
|
283
|
+
const absR = r + rowStart;
|
|
284
|
+
const cells = [];
|
|
285
|
+
for (let c = 0; c < colCount; c++) {
|
|
286
|
+
const absC = c + colStart;
|
|
287
|
+
const merge = mergeOrigins.get(key(absR, absC));
|
|
288
|
+
if (insideMerge.has(key(absR, absC)) && !merge) {
|
|
289
|
+
const verticalParent = verticalMergeParent(worksheet.merges, absR, absC);
|
|
290
|
+
if (verticalParent && absC === verticalParent.startColumn) cells.push(makeVerticalContinuation(verticalParent, colWindowEnd));
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const ws = cellMatrix[r]?.[c];
|
|
294
|
+
let text = ws ? resolveCellText(ws, sharedStrings, styles, date1904) : "";
|
|
295
|
+
if (text.length > textBudget) text = text.slice(0, Math.max(0, textBudget));
|
|
296
|
+
textBudget -= text.length;
|
|
297
|
+
const xf = ws && ws.styleIndex !== void 0 ? styles.cellXfs[ws.styleIndex] : void 0;
|
|
298
|
+
const baseRunProps = xf ? runPropsFromXf(xf, styles) : {};
|
|
299
|
+
const runProps = scaled ? scaleRunFont(baseRunProps, printScale) : baseRunProps;
|
|
300
|
+
const alignment = xf ? alignmentFromXf(xf) : void 0;
|
|
301
|
+
const shading = xf ? shadingFromXf(xf, styles) : void 0;
|
|
302
|
+
const borders = xf ? bordersFromXf(xf, styles) : void 0;
|
|
303
|
+
if (text.length > 0 && !merge && ws && (ws.type === "s" || ws.type === "str" || ws.type === "inlineStr") && (alignment === void 0 || alignment === "left")) {
|
|
304
|
+
let availTwips = columnWidths[c];
|
|
305
|
+
let cc = c + 1;
|
|
306
|
+
while (cc < colCount && !cellHasContent(cellMatrix[r]?.[cc])) {
|
|
307
|
+
availTwips += columnWidths[cc];
|
|
308
|
+
cc++;
|
|
309
|
+
}
|
|
310
|
+
if (cc < colCount) {
|
|
311
|
+
const charsFit = Math.max(1, Math.round(availTwips / TWIPS_PER_EXCEL_CHAR));
|
|
312
|
+
if (text.length > charsFit) text = text.slice(0, charsFit);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const visibleEndCol = merge ? Math.min(merge.endColumn, colWindowEnd) : 0;
|
|
316
|
+
const properties = {
|
|
317
|
+
...merge && visibleEndCol > merge.startColumn ? { gridSpan: visibleEndCol - merge.startColumn + 1 } : {},
|
|
318
|
+
...merge && Math.min(merge.endRow, rowWindowEnd) > merge.startRow ? { vMerge: "restart" } : {},
|
|
319
|
+
...shading ? { shading } : {},
|
|
320
|
+
...borders ? { borders } : {}
|
|
321
|
+
};
|
|
322
|
+
const paragraphProps = alignment ? { alignment } : {};
|
|
323
|
+
cells.push({
|
|
324
|
+
properties,
|
|
325
|
+
content: [{
|
|
326
|
+
kind: "paragraph",
|
|
327
|
+
paragraph: {
|
|
328
|
+
properties: paragraphProps,
|
|
329
|
+
runs: text.length > 0 ? [{
|
|
330
|
+
text,
|
|
331
|
+
properties: runProps
|
|
332
|
+
}] : []
|
|
333
|
+
}
|
|
334
|
+
}]
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
const baseRowProps = rowHeightMap.get(r);
|
|
338
|
+
const scaledRowProps = scaled && baseRowProps?.heightTwips !== void 0 ? {
|
|
339
|
+
...baseRowProps,
|
|
340
|
+
heightTwips: Math.max(1, Math.round(baseRowProps.heightTwips * printScale))
|
|
341
|
+
} : baseRowProps ?? {};
|
|
342
|
+
const isTitleRow = print.titleRows !== void 0 && absR >= print.titleRows.startRow && absR <= print.titleRows.endRow;
|
|
343
|
+
const rowProps = {
|
|
344
|
+
...scaledRowProps,
|
|
345
|
+
...isTitleRow ? { isHeader: true } : {},
|
|
346
|
+
...breakRows.has(absR) ? { pageBreakBefore: true } : {}
|
|
347
|
+
};
|
|
348
|
+
rows.push({
|
|
349
|
+
properties: rowProps,
|
|
350
|
+
cells
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
const thin = {
|
|
354
|
+
style: "single",
|
|
355
|
+
sizeEighthPt: 4
|
|
356
|
+
};
|
|
357
|
+
const centered = worksheet.printOptions?.horizontalCentered === true;
|
|
358
|
+
return [{
|
|
359
|
+
kind: "table",
|
|
360
|
+
table: {
|
|
361
|
+
properties: {
|
|
362
|
+
...print.gridLines ? { borders: {
|
|
363
|
+
top: thin,
|
|
364
|
+
bottom: thin,
|
|
365
|
+
left: thin,
|
|
366
|
+
right: thin,
|
|
367
|
+
insideH: thin,
|
|
368
|
+
insideV: thin
|
|
369
|
+
} } : {},
|
|
370
|
+
...centered ? { alignment: "center" } : {}
|
|
371
|
+
},
|
|
372
|
+
grid: columnWidths,
|
|
373
|
+
rows
|
|
374
|
+
}
|
|
375
|
+
}];
|
|
376
|
+
}
|
|
377
|
+
function verticalMergeParent(merges, row, column) {
|
|
378
|
+
for (const m of merges) if (column >= m.startColumn && column <= m.endColumn && row > m.startRow && row <= m.endRow && m.endRow > m.startRow) return m;
|
|
379
|
+
}
|
|
380
|
+
function makeVerticalContinuation(merge, colWindowEnd) {
|
|
381
|
+
const span = Math.min(merge.endColumn, colWindowEnd) - merge.startColumn + 1;
|
|
382
|
+
return {
|
|
383
|
+
properties: {
|
|
384
|
+
vMerge: "continue",
|
|
385
|
+
...span > 1 ? { gridSpan: span } : {}
|
|
386
|
+
},
|
|
387
|
+
content: [{
|
|
388
|
+
kind: "paragraph",
|
|
389
|
+
paragraph: {
|
|
390
|
+
properties: {},
|
|
391
|
+
runs: []
|
|
392
|
+
}
|
|
393
|
+
}]
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
function resolveCellText(cell, sharedStrings, styles, date1904) {
|
|
397
|
+
if (cell.type === "inlineStr") return cell.inlineText ?? "";
|
|
398
|
+
if (cell.type === "s") {
|
|
399
|
+
const idx = Number(cell.rawValue);
|
|
400
|
+
if (Number.isInteger(idx) && idx >= 0 && idx < sharedStrings.length) return sharedStrings[idx];
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
if (cell.type === "b") return cell.rawValue === "1" ? "TRUE" : "FALSE";
|
|
404
|
+
if (cell.type === "str" || cell.type === "e" || cell.type === "d") return cell.rawValue;
|
|
405
|
+
const numFmtId = (cell.styleIndex !== void 0 ? styles.cellXfs[cell.styleIndex] : void 0)?.numFmtId ?? 0;
|
|
406
|
+
return applyNumberFormat(cell.rawValue, numFmtId, styles.numFmts, date1904);
|
|
407
|
+
}
|
|
408
|
+
function runPropsFromXf(xf, styles) {
|
|
409
|
+
if (!xf.applyFont && xf.fontId === 0) return {};
|
|
410
|
+
const font = styles.fonts[xf.fontId];
|
|
411
|
+
if (!font) return {};
|
|
412
|
+
const props = {};
|
|
413
|
+
if (font.bold) props.bold = true;
|
|
414
|
+
if (font.italic) props.italic = true;
|
|
415
|
+
if (font.sizePt !== void 0) props.fontSizeHalfPoints = Math.round(font.sizePt * 2);
|
|
416
|
+
if (font.colorHex) props.colorHex = font.colorHex;
|
|
417
|
+
return props;
|
|
418
|
+
}
|
|
419
|
+
function alignmentFromXf(xf) {
|
|
420
|
+
const align = xf.alignment;
|
|
421
|
+
if (!align) return void 0;
|
|
422
|
+
return mapAlignment(align.horizontal);
|
|
423
|
+
}
|
|
424
|
+
function mapAlignment(h) {
|
|
425
|
+
if (!h) return void 0;
|
|
426
|
+
if (h === "left") return "left";
|
|
427
|
+
if (h === "right") return "right";
|
|
428
|
+
if (h === "center" || h === "centerContinuous") return "center";
|
|
429
|
+
if (h === "justify") return "both";
|
|
430
|
+
if (h === "distributed") return "distribute";
|
|
431
|
+
}
|
|
432
|
+
function shadingFromXf(xf, styles) {
|
|
433
|
+
if (xf.applyFill === false) return void 0;
|
|
434
|
+
if (xf.fillId === 0 || xf.fillId === 1) {
|
|
435
|
+
if (!xf.applyFill) return void 0;
|
|
436
|
+
}
|
|
437
|
+
const fill = styles.fills[xf.fillId];
|
|
438
|
+
if (!fill || fill.patternType !== "solid" || !fill.fgColorHex) return void 0;
|
|
439
|
+
return { colorHex: fill.fgColorHex };
|
|
440
|
+
}
|
|
441
|
+
function bordersFromXf(xf, styles) {
|
|
442
|
+
if (xf.applyBorder === false) return void 0;
|
|
443
|
+
if (xf.borderId === 0 && !xf.applyBorder) return void 0;
|
|
444
|
+
const border = styles.borders[xf.borderId];
|
|
445
|
+
if (!border) return void 0;
|
|
446
|
+
const out = {};
|
|
447
|
+
const top = mapBorderEdge(border.top);
|
|
448
|
+
const right = mapBorderEdge(border.right);
|
|
449
|
+
const bottom = mapBorderEdge(border.bottom);
|
|
450
|
+
const left = mapBorderEdge(border.left);
|
|
451
|
+
if (top) out.top = top;
|
|
452
|
+
if (right) out.right = right;
|
|
453
|
+
if (bottom) out.bottom = bottom;
|
|
454
|
+
if (left) out.left = left;
|
|
455
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
456
|
+
}
|
|
457
|
+
function mapBorderEdge(edge) {
|
|
458
|
+
if (!edge || !edge.style || edge.style === "none") return void 0;
|
|
459
|
+
const { style, sizeEighthPt } = mapBorderStyle(edge.style);
|
|
460
|
+
return {
|
|
461
|
+
style,
|
|
462
|
+
sizeEighthPt,
|
|
463
|
+
...edge.colorHex ? { colorHex: edge.colorHex } : {}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function mapBorderStyle(style) {
|
|
467
|
+
switch (style) {
|
|
468
|
+
case "hair": return {
|
|
469
|
+
style: "single",
|
|
470
|
+
sizeEighthPt: 2
|
|
471
|
+
};
|
|
472
|
+
case "thin": return {
|
|
473
|
+
style: "single",
|
|
474
|
+
sizeEighthPt: 4
|
|
475
|
+
};
|
|
476
|
+
case "medium":
|
|
477
|
+
case "mediumDashed":
|
|
478
|
+
case "mediumDashDot":
|
|
479
|
+
case "mediumDashDotDot": return {
|
|
480
|
+
style: "single",
|
|
481
|
+
sizeEighthPt: 8
|
|
482
|
+
};
|
|
483
|
+
case "thick": return {
|
|
484
|
+
style: "thick",
|
|
485
|
+
sizeEighthPt: 12
|
|
486
|
+
};
|
|
487
|
+
case "dashed":
|
|
488
|
+
case "dashDot":
|
|
489
|
+
case "dashDotDot":
|
|
490
|
+
case "slantDashDot": return {
|
|
491
|
+
style: "dashed",
|
|
492
|
+
sizeEighthPt: 4
|
|
493
|
+
};
|
|
494
|
+
case "dotted": return {
|
|
495
|
+
style: "dotted",
|
|
496
|
+
sizeEighthPt: 4
|
|
497
|
+
};
|
|
498
|
+
case "double": return {
|
|
499
|
+
style: "double",
|
|
500
|
+
sizeEighthPt: 4
|
|
501
|
+
};
|
|
502
|
+
default: return {
|
|
503
|
+
style: "single",
|
|
504
|
+
sizeEighthPt: 4
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
function key(row, col) {
|
|
509
|
+
return `${row},${col}`;
|
|
510
|
+
}
|
|
511
|
+
function cellHasContent(cell) {
|
|
512
|
+
return !!cell && (cell.rawValue !== "" || cell.inlineText !== void 0);
|
|
513
|
+
}
|
|
514
|
+
//#endregion
|
|
515
|
+
export { convertXlsxToPdf, convertXlsxToPdfSync };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare function concat(arrays: ReadonlyArray<Uint8Array>): Uint8Array;
|
|
2
|
+
export declare function tlv(tag: number, content: Uint8Array): Uint8Array;
|
|
3
|
+
export declare const seq: (...items: Array<Uint8Array>) => Uint8Array;
|
|
4
|
+
export declare const set: (...items: Array<Uint8Array>) => Uint8Array;
|
|
5
|
+
export declare const octetString: (bytes: Uint8Array) => Uint8Array;
|
|
6
|
+
export declare const nullValue: () => Uint8Array;
|
|
7
|
+
export declare const explicit: (tagNum: number, content: Uint8Array) => Uint8Array;
|
|
8
|
+
export declare function oid(dotted: string): Uint8Array;
|
|
9
|
+
export declare function integer(value: number | Uint8Array): Uint8Array;
|
|
10
|
+
export declare function cmsTime(d: Date): Uint8Array;
|
|
11
|
+
export declare function setOfBody(items: ReadonlyArray<Uint8Array>): Uint8Array;
|
|
12
|
+
export interface Tlv {
|
|
13
|
+
readonly tag: number;
|
|
14
|
+
readonly contentStart: number;
|
|
15
|
+
readonly contentEnd: number;
|
|
16
|
+
readonly end: number;
|
|
17
|
+
}
|
|
18
|
+
export declare function children(buf: Uint8Array, parent: Tlv): Array<Tlv>;
|
|
19
|
+
export declare function readTlv(buf: Uint8Array, offset: number): Tlv;
|
|
20
|
+
export declare function certIssuerAndSerial(cert: Uint8Array): {
|
|
21
|
+
readonly issuer: Uint8Array;
|
|
22
|
+
readonly serial: Uint8Array;
|
|
23
|
+
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
//#region src/crypto/asn1.ts
|
|
2
|
+
var textEncoder = new TextEncoder();
|
|
3
|
+
function concat(arrays) {
|
|
4
|
+
let total = 0;
|
|
5
|
+
for (const a of arrays) total += a.length;
|
|
6
|
+
const out = new Uint8Array(total);
|
|
7
|
+
let off = 0;
|
|
8
|
+
for (const a of arrays) {
|
|
9
|
+
out.set(a, off);
|
|
10
|
+
off += a.length;
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
function encodeLength(len) {
|
|
15
|
+
if (len < 128) return new Uint8Array([len]);
|
|
16
|
+
const bytes = [];
|
|
17
|
+
let n = len;
|
|
18
|
+
while (n > 0) {
|
|
19
|
+
bytes.unshift(n & 255);
|
|
20
|
+
n = Math.floor(n / 256);
|
|
21
|
+
}
|
|
22
|
+
return new Uint8Array([128 | bytes.length, ...bytes]);
|
|
23
|
+
}
|
|
24
|
+
function tlv(tag, content) {
|
|
25
|
+
const len = encodeLength(content.length);
|
|
26
|
+
const out = new Uint8Array(1 + len.length + content.length);
|
|
27
|
+
out[0] = tag;
|
|
28
|
+
out.set(len, 1);
|
|
29
|
+
out.set(content, 1 + len.length);
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
var seq = (...items) => tlv(48, concat(items));
|
|
33
|
+
var set = (...items) => tlv(49, concat(items));
|
|
34
|
+
var octetString = (bytes) => tlv(4, bytes);
|
|
35
|
+
var nullValue = () => tlv(5, new Uint8Array(0));
|
|
36
|
+
var explicit = (tagNum, content) => tlv(160 | tagNum, content);
|
|
37
|
+
function base128(v) {
|
|
38
|
+
const out = [v & 127];
|
|
39
|
+
let n = Math.floor(v / 128);
|
|
40
|
+
while (n > 0) {
|
|
41
|
+
out.unshift(n & 127 | 128);
|
|
42
|
+
n = Math.floor(n / 128);
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
function oid(dotted) {
|
|
47
|
+
const parts = dotted.split(".").map((p) => Number(p));
|
|
48
|
+
const body = [...base128(40 * parts[0] + parts[1])];
|
|
49
|
+
for (let i = 2; i < parts.length; i++) body.push(...base128(parts[i]));
|
|
50
|
+
return tlv(6, new Uint8Array(body));
|
|
51
|
+
}
|
|
52
|
+
function integer(value) {
|
|
53
|
+
let bytes;
|
|
54
|
+
if (typeof value === "number") {
|
|
55
|
+
bytes = [];
|
|
56
|
+
let n = value;
|
|
57
|
+
if (n === 0) bytes = [0];
|
|
58
|
+
while (n > 0) {
|
|
59
|
+
bytes.unshift(n & 255);
|
|
60
|
+
n = Math.floor(n / 256);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
bytes = [...value];
|
|
64
|
+
while (bytes.length > 1 && bytes[0] === 0 && (bytes[1] & 128) === 0) bytes.shift();
|
|
65
|
+
}
|
|
66
|
+
if (bytes.length === 0) bytes = [0];
|
|
67
|
+
if (bytes[0] & 128) bytes.unshift(0);
|
|
68
|
+
return tlv(2, new Uint8Array(bytes));
|
|
69
|
+
}
|
|
70
|
+
var pad2 = (n) => n.toString().padStart(2, "0");
|
|
71
|
+
function cmsTime(d) {
|
|
72
|
+
const y = d.getUTCFullYear();
|
|
73
|
+
const mmddhhmmss = pad2(d.getUTCMonth() + 1) + pad2(d.getUTCDate()) + pad2(d.getUTCHours()) + pad2(d.getUTCMinutes()) + pad2(d.getUTCSeconds());
|
|
74
|
+
if (y >= 1950 && y < 2050) return tlv(23, textEncoder.encode(pad2(y % 100) + mmddhhmmss + "Z"));
|
|
75
|
+
return tlv(24, textEncoder.encode(String(y) + mmddhhmmss + "Z"));
|
|
76
|
+
}
|
|
77
|
+
function compareDer(a, b) {
|
|
78
|
+
const n = Math.min(a.length, b.length);
|
|
79
|
+
for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
|
|
80
|
+
return a.length - b.length;
|
|
81
|
+
}
|
|
82
|
+
function setOfBody(items) {
|
|
83
|
+
return concat([...items].sort(compareDer));
|
|
84
|
+
}
|
|
85
|
+
function readTlv(buf, offset) {
|
|
86
|
+
const tag = buf[offset];
|
|
87
|
+
let i = offset + 1;
|
|
88
|
+
let len = buf[i];
|
|
89
|
+
i++;
|
|
90
|
+
if (len & 128) {
|
|
91
|
+
const n = len & 127;
|
|
92
|
+
len = 0;
|
|
93
|
+
for (let k = 0; k < n; k++) {
|
|
94
|
+
len = len * 256 + buf[i];
|
|
95
|
+
i++;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
tag,
|
|
100
|
+
contentStart: i,
|
|
101
|
+
contentEnd: i + len,
|
|
102
|
+
end: i + len
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function certIssuerAndSerial(cert) {
|
|
106
|
+
let p = readTlv(cert, readTlv(cert, 0).contentStart).contentStart;
|
|
107
|
+
let t = readTlv(cert, p);
|
|
108
|
+
if (t.tag === 160) {
|
|
109
|
+
p = t.end;
|
|
110
|
+
t = readTlv(cert, p);
|
|
111
|
+
}
|
|
112
|
+
const serial = cert.slice(p, t.end);
|
|
113
|
+
p = t.end;
|
|
114
|
+
t = readTlv(cert, p);
|
|
115
|
+
p = t.end;
|
|
116
|
+
t = readTlv(cert, p);
|
|
117
|
+
return {
|
|
118
|
+
issuer: cert.slice(p, t.end),
|
|
119
|
+
serial
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { certIssuerAndSerial, cmsTime, concat, explicit, integer, nullValue, octetString, oid, seq, set, setOfBody, tlv };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface CmsParams {
|
|
2
|
+
readonly certificate: Uint8Array;
|
|
3
|
+
readonly extraCertificates?: ReadonlyArray<Uint8Array>;
|
|
4
|
+
readonly messageDigest: Uint8Array;
|
|
5
|
+
readonly signingTime: Date;
|
|
6
|
+
readonly signatureAlgorithm?: 'rsa' | 'ecdsa';
|
|
7
|
+
readonly sign: (signedAttrsDer: Uint8Array) => Promise<Uint8Array>;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildPkcs7Detached(params: CmsParams): Promise<Uint8Array>;
|