@shbernal/ts-xlsx 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/autofilter.d.ts +1 -1
- package/dist/core/autofilter.js +3 -5
- package/dist/core/axis-handle.d.ts +8 -0
- package/dist/core/axis-handle.js +14 -0
- package/dist/core/cell.d.ts +24 -0
- package/dist/core/cell.js +9 -1
- package/dist/core/column.d.ts +4 -1
- package/dist/core/column.js +31 -35
- package/dist/core/conditional-formatting.d.ts +5 -5
- package/dist/core/conditional-formatting.js +11 -25
- package/dist/core/data-validation.d.ts +3 -3
- package/dist/core/data-validation.js +7 -15
- package/dist/core/image.d.ts +1 -1
- package/dist/core/image.js +2 -4
- package/dist/core/merge-index.d.ts +31 -0
- package/dist/core/merge-index.js +60 -0
- package/dist/core/merge.d.ts +0 -10
- package/dist/core/merge.js +0 -8
- package/dist/core/page-setup.d.ts +72 -2
- package/dist/core/page-setup.js +34 -8
- package/dist/core/pivot-table.d.ts +1 -1
- package/dist/core/pivot-table.js +4 -8
- package/dist/core/row.d.ts +4 -1
- package/dist/core/row.js +19 -23
- package/dist/core/style.d.ts +51 -7
- package/dist/core/style.js +29 -34
- package/dist/core/table.d.ts +1 -1
- package/dist/core/table.js +3 -5
- package/dist/core/used-extent.d.ts +44 -0
- package/dist/core/used-extent.js +102 -0
- package/dist/core/worksheet.d.ts +17 -6
- package/dist/core/worksheet.js +48 -42
- package/dist/customui/ribbon.js +4 -6
- package/dist/io/opc/inflate.js +1 -1
- package/dist/io/opc/part-paths.d.ts +1 -0
- package/dist/io/opc/part-paths.js +15 -0
- package/dist/io/opc/read-opc.d.ts +22 -3
- package/dist/io/opc/read-opc.js +11 -39
- package/dist/io/opc/rels.d.ts +1 -6
- package/dist/io/opc/rels.js +1 -4
- package/dist/io/style/xf-style.d.ts +26 -2
- package/dist/io/style/xf-style.js +6 -0
- package/dist/io/xlsb/read-styles.js +6 -3
- package/dist/io/xlsb/read.d.ts +1 -1
- package/dist/io/xlsb/read.js +5 -8
- package/dist/io/xlsx/cell-accumulator.d.ts +1 -1
- package/dist/io/xlsx/cell-accumulator.js +1 -1
- package/dist/io/xlsx/cell-value.js +1 -1
- package/dist/io/xlsx/color-xml.js +1 -1
- package/dist/io/xlsx/comments.js +2 -1
- package/dist/io/xlsx/conditional-formatting.d.ts +3 -2
- package/dist/io/xlsx/conditional-formatting.js +22 -21
- package/dist/io/xlsx/data-validation.d.ts +9 -7
- package/dist/io/xlsx/data-validation.js +10 -9
- package/dist/io/xlsx/edit-vba.js +4 -11
- package/dist/io/xlsx/hyperlinks.d.ts +4 -2
- package/dist/io/xlsx/hyperlinks.js +20 -17
- package/dist/io/xlsx/images.js +15 -14
- package/dist/io/xlsx/package-plan.d.ts +9 -1
- package/dist/io/xlsx/package-plan.js +29 -16
- package/dist/io/xlsx/part-names.d.ts +41 -0
- package/dist/io/xlsx/part-names.js +46 -0
- package/dist/io/xlsx/read-pivot.js +2 -1
- package/dist/io/xlsx/read-rows.js +12 -13
- package/dist/io/xlsx/read-shared-strings.js +2 -1
- package/dist/io/xlsx/read-styles.d.ts +1 -1
- package/dist/io/xlsx/read-styles.js +63 -42
- package/dist/io/xlsx/read-worksheet.d.ts +10 -1
- package/dist/io/xlsx/read-worksheet.js +43 -56
- package/dist/io/xlsx/read.d.ts +2 -3
- package/dist/io/xlsx/read.js +81 -73
- package/dist/io/xlsx/rich-runs.d.ts +1 -1
- package/dist/io/xlsx/rich-runs.js +2 -1
- package/dist/io/xlsx/sheet-properties.js +21 -28
- package/dist/io/xlsx/styles.js +23 -20
- package/dist/io/xlsx/tables.js +2 -1
- package/dist/io/xlsx/theme-xml.js +1 -1
- package/dist/io/xlsx/threaded-comments.js +2 -1
- package/dist/io/xlsx/workbook-xml.js +29 -28
- package/dist/io/xlsx/worksheet-xml.d.ts +1 -1
- package/dist/io/xlsx/worksheet-xml.js +14 -16
- package/dist/io/xlsx/write-stream.d.ts +6 -0
- package/dist/io/xlsx/write-stream.js +30 -22
- package/dist/io/xlsx/write.d.ts +5 -0
- package/dist/io/xlsx/write.js +155 -131
- package/dist/token-set.d.ts +15 -0
- package/dist/token-set.js +4 -0
- package/dist/vba/cfb-format.d.ts +24 -0
- package/dist/vba/cfb-format.js +12 -0
- package/dist/vba/cfb-writer.js +17 -17
- package/dist/vba/cfb.js +1 -7
- package/dist/vba/ms-ovba.js +32 -11
- package/dist/vba/project.js +13 -13
- package/dist/vba/vba-encoding.js +1 -1
- package/dist/xml/xml-read.d.ts +59 -74
- package/dist/xml/xml-read.js +83 -176
- package/dist/xml/xml-scan.d.ts +100 -0
- package/dist/xml/xml-scan.js +208 -0
- package/dist/xml/xml.d.ts +1 -1
- package/package.json +2 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
export interface XmlAttributes {
|
|
2
|
+
readonly [name: string]: string;
|
|
3
|
+
}
|
|
4
|
+
export type XmlEvent = {
|
|
5
|
+
readonly kind: 'open';
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly attrs: XmlAttributes;
|
|
8
|
+
readonly selfClosing: boolean;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'text';
|
|
11
|
+
readonly text: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: 'close';
|
|
14
|
+
readonly name: string;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Decode XML character references and the five predefined entities. An unrecognised
|
|
18
|
+
* `&name;` is left verbatim rather than expanded: there is no DTD, so there is nothing
|
|
19
|
+
* to expand it to, and refusing to invent one is what makes entity-expansion attacks
|
|
20
|
+
* impossible.
|
|
21
|
+
*/
|
|
22
|
+
export declare function decodeEntities(value: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* The SpreadsheetML `_xHHHH_` escape, in the only place it may appear: a complete cell-text value.
|
|
25
|
+
*
|
|
26
|
+
* The mirror of `escapeSpreadsheetText` in `./xml.ts`, and it sits here rather than beside it for
|
|
27
|
+
* the same reason `decodeEntities` sits apart from `escapeText`: the write helpers carry an
|
|
28
|
+
* `AuthoringError` and a whole serialisation vocabulary the reader has no business importing.
|
|
29
|
+
*
|
|
30
|
+
* **One left-to-right pass, and that is load-bearing.** `005F` maps to `_` like any other code
|
|
31
|
+
* point, with no special case, because a single pass already gives the underscore escape its
|
|
32
|
+
* meaning: in `_x005F_x0041_` the match at 0 yields `_` and scanning resumes at `x0041_`, which has
|
|
33
|
+
* no leading underscore left to start an escape. So the value reads back as the literal seven
|
|
34
|
+
* characters `_x0041_` the author wrote. Decoding `_x005F_` in a pass of its own, before or after
|
|
35
|
+
* the rest, collapses that to `A` and loses the distinction the encoder went to trouble to keep.
|
|
36
|
+
* Excel agrees: it reads that cell as `_x0041_`.
|
|
37
|
+
*
|
|
38
|
+
* The decode is unconditional, not a repair of characters XML cannot carry. Excel reads
|
|
39
|
+
* `a_x0009_b` as a tab even though a literal tab would have been perfectly legal there, so a
|
|
40
|
+
* decoder that only handled the illegal range would disagree with Excel on files Excel wrote.
|
|
41
|
+
*/
|
|
42
|
+
export declare function decodeSpreadsheetText(value: string): string;
|
|
43
|
+
export declare function parseAttributes(source: string): XmlAttributes;
|
|
44
|
+
export type Markup = {
|
|
45
|
+
readonly kind: 'comment' | 'pi' | 'declaration';
|
|
46
|
+
readonly next: number;
|
|
47
|
+
} | {
|
|
48
|
+
readonly kind: 'cdata';
|
|
49
|
+
readonly contentStart: number;
|
|
50
|
+
readonly contentEnd: number;
|
|
51
|
+
readonly next: number;
|
|
52
|
+
};
|
|
53
|
+
export declare function markupAt(source: string, lt: number): Markup | undefined;
|
|
54
|
+
export interface Tag {
|
|
55
|
+
readonly close: boolean;
|
|
56
|
+
readonly name: string;
|
|
57
|
+
readonly attrSource: string;
|
|
58
|
+
readonly selfClosing: boolean;
|
|
59
|
+
/** One past the tag's `>`, so a caller capturing verbatim source can slice up to it. */
|
|
60
|
+
readonly next: number;
|
|
61
|
+
}
|
|
62
|
+
export declare function tagAt(source: string, lt: number): Tag;
|
|
63
|
+
/**
|
|
64
|
+
* Scan an XML document as a *pull* stream of {@link XmlEvent}s in a single O(n) pass with no
|
|
65
|
+
* recursion. This is the parser's core; {@link parseXml} is a thin push adapter over it. A
|
|
66
|
+
* consumer that must produce output incrementally (the streaming row reader) pulls events and
|
|
67
|
+
* yields as it goes, holding only its own running state; a push callback cannot.
|
|
68
|
+
*
|
|
69
|
+
* Throws {@link XmlParseError} on malformed markup.
|
|
70
|
+
*/
|
|
71
|
+
export declare function xmlEvents(source: string): Generator<XmlEvent>;
|
|
72
|
+
/** Strip a namespace prefix from a qualified name (`r:id` → `id`, `sheet` → `sheet`). */
|
|
73
|
+
export declare function localName(qualified: string): string;
|
|
74
|
+
/** An OOXML boolean that is on when present with no value (`<b/>` is bold) and off only on an
|
|
75
|
+
* explicit `"0"`/`"false"`; absence reads as on. */
|
|
76
|
+
export declare function boolPresent(val: string | undefined): boolean;
|
|
77
|
+
/** An OOXML boolean that is on only when explicitly `"1"`/`"true"`; anything else, including
|
|
78
|
+
* absence and a truthy-looking `"0"`, is off. */
|
|
79
|
+
export declare function boolStrict(val: string | undefined): boolean;
|
|
80
|
+
/** An optional OOXML boolean: `undefined` when the attribute is absent or carries an unrecognised
|
|
81
|
+
* token, otherwise its `"1"`/`"true"` vs `"0"`/`"false"` value. Lets a caller store only the
|
|
82
|
+
* attributes the source actually carried, so a re-write stays byte-clean. */
|
|
83
|
+
export declare function boolTristate(val: string | undefined): boolean | undefined;
|
|
84
|
+
/** An OOXML integer attribute at or above `min` (default: unbounded below); `undefined` when the
|
|
85
|
+
* attribute is absent, blank, fractional, not a number, or below the floor. Integers past
|
|
86
|
+
* `Number.MAX_SAFE_INTEGER` read as `undefined` too: no index or count is usable out there, and
|
|
87
|
+
* arithmetic on one silently lies. */
|
|
88
|
+
export declare function numInteger(val: string | undefined, min?: number): number | undefined;
|
|
89
|
+
/** An OOXML decimal attribute at or above `min` (default: unbounded below); `undefined` when the
|
|
90
|
+
* attribute is absent, blank, not a number, or below the floor. Infinities are not finite numbers
|
|
91
|
+
* and read as `undefined`. */
|
|
92
|
+
export declare function numFinite(val: string | undefined, min?: number): number | undefined;
|
|
93
|
+
/** Read an operand's text as a number only when it is a canonical decimal literal (optional sign,
|
|
94
|
+
* digits, optional fraction). A cell reference, defined name, expression, or exotically-spelled
|
|
95
|
+
* number (`1E5`, hex) keeps its verbatim text, so it is neither coerced to `NaN` and lost nor
|
|
96
|
+
* re-spelled into a number that would not re-write byte-clean. Callers layer their own type rules
|
|
97
|
+
* (a data-validation `list`/`custom` operand stays a string regardless of what it looks like). */
|
|
98
|
+
export declare function coerceNumericLiteral(text: string): string | number;
|
|
99
|
+
/** Narrow an enumerated attribute through its guard; `undefined` when absent or not a member. */
|
|
100
|
+
export declare function enumToken<T extends string>(val: string | undefined, isMember: (candidate: string) => candidate is T): T | undefined;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { XmlParseError } from './errors.js';
|
|
2
|
+
const PREDEFINED_ENTITIES = new Map([
|
|
3
|
+
['amp', '&'],
|
|
4
|
+
['lt', '<'],
|
|
5
|
+
['gt', '>'],
|
|
6
|
+
['quot', '"'],
|
|
7
|
+
['apos', "'"],
|
|
8
|
+
]);
|
|
9
|
+
const ENTITY = /&(#x[0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);/g;
|
|
10
|
+
export function decodeEntities(value) {
|
|
11
|
+
if (!value.includes('&'))
|
|
12
|
+
return value;
|
|
13
|
+
return value.replace(ENTITY, (match, body) => {
|
|
14
|
+
if (body.charCodeAt(0) === 0x23) {
|
|
15
|
+
const codePoint = body.charCodeAt(1) === 0x78
|
|
16
|
+
? Number.parseInt(body.slice(2), 16)
|
|
17
|
+
: Number.parseInt(body.slice(1), 10);
|
|
18
|
+
if (!Number.isInteger(codePoint) || codePoint < 0 || codePoint > 0x10ffff)
|
|
19
|
+
return match;
|
|
20
|
+
try {
|
|
21
|
+
return String.fromCodePoint(codePoint);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return match;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return PREDEFINED_ENTITIES.get(body) ?? match;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export function decodeSpreadsheetText(value) {
|
|
31
|
+
if (!value.includes('_'))
|
|
32
|
+
return value;
|
|
33
|
+
return value.replace(/_x([0-9A-Fa-f]{4})_/g, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
|
|
34
|
+
}
|
|
35
|
+
const ATTRIBUTE = /([^\s=/>]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
36
|
+
export function parseAttributes(source) {
|
|
37
|
+
const attrs = Object.create(null);
|
|
38
|
+
ATTRIBUTE.lastIndex = 0;
|
|
39
|
+
let match = ATTRIBUTE.exec(source);
|
|
40
|
+
while (match !== null) {
|
|
41
|
+
const value = match[2] ?? match[3] ?? '';
|
|
42
|
+
attrs[match[1]] = decodeEntities(value);
|
|
43
|
+
match = ATTRIBUTE.exec(source);
|
|
44
|
+
}
|
|
45
|
+
return attrs;
|
|
46
|
+
}
|
|
47
|
+
function findTagEnd(source, start) {
|
|
48
|
+
let quote = '';
|
|
49
|
+
for (let i = start + 1; i < source.length; i++) {
|
|
50
|
+
const ch = source[i];
|
|
51
|
+
if (quote !== '') {
|
|
52
|
+
if (ch === quote)
|
|
53
|
+
quote = '';
|
|
54
|
+
}
|
|
55
|
+
else if (ch === '"' || ch === "'") {
|
|
56
|
+
quote = ch;
|
|
57
|
+
}
|
|
58
|
+
else if (ch === '>') {
|
|
59
|
+
return i;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
throw new XmlParseError('unterminated tag: missing ">"');
|
|
63
|
+
}
|
|
64
|
+
function skipDeclaration(source, start) {
|
|
65
|
+
let depth = 0;
|
|
66
|
+
for (let i = start; i < source.length; i++) {
|
|
67
|
+
const ch = source[i];
|
|
68
|
+
if (ch === '[')
|
|
69
|
+
depth++;
|
|
70
|
+
else if (ch === ']')
|
|
71
|
+
depth--;
|
|
72
|
+
else if (ch === '>' && depth <= 0)
|
|
73
|
+
return i + 1;
|
|
74
|
+
}
|
|
75
|
+
throw new XmlParseError('unterminated markup declaration: missing ">"');
|
|
76
|
+
}
|
|
77
|
+
export function markupAt(source, lt) {
|
|
78
|
+
if (source.startsWith('<!--', lt)) {
|
|
79
|
+
const end = source.indexOf('-->', lt + 4);
|
|
80
|
+
if (end === -1)
|
|
81
|
+
throw new XmlParseError('unterminated comment');
|
|
82
|
+
return { kind: 'comment', next: end + 3 };
|
|
83
|
+
}
|
|
84
|
+
if (source.startsWith('<![CDATA[', lt)) {
|
|
85
|
+
const end = source.indexOf(']]>', lt + 9);
|
|
86
|
+
if (end === -1)
|
|
87
|
+
throw new XmlParseError('unterminated CDATA section');
|
|
88
|
+
return { kind: 'cdata', contentStart: lt + 9, contentEnd: end, next: end + 3 };
|
|
89
|
+
}
|
|
90
|
+
if (source.startsWith('<?', lt)) {
|
|
91
|
+
const end = source.indexOf('?>', lt + 2);
|
|
92
|
+
if (end === -1)
|
|
93
|
+
throw new XmlParseError('unterminated processing instruction');
|
|
94
|
+
return { kind: 'pi', next: end + 2 };
|
|
95
|
+
}
|
|
96
|
+
if (source.startsWith('<!', lt))
|
|
97
|
+
return { kind: 'declaration', next: skipDeclaration(source, lt) };
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
export function tagAt(source, lt) {
|
|
101
|
+
const gt = findTagEnd(source, lt);
|
|
102
|
+
const raw = source.slice(lt + 1, gt);
|
|
103
|
+
const next = gt + 1;
|
|
104
|
+
if (raw.charCodeAt(0) === 0x2f) {
|
|
105
|
+
return { close: true, name: raw.slice(1).trim(), attrSource: '', selfClosing: false, next };
|
|
106
|
+
}
|
|
107
|
+
const selfClosing = raw.charCodeAt(raw.length - 1) === 0x2f;
|
|
108
|
+
const body = selfClosing ? raw.slice(0, -1) : raw;
|
|
109
|
+
const nameEnd = firstWhitespace(body);
|
|
110
|
+
return {
|
|
111
|
+
close: false,
|
|
112
|
+
name: nameEnd === -1 ? body : body.slice(0, nameEnd),
|
|
113
|
+
attrSource: nameEnd === -1 ? '' : body.slice(nameEnd),
|
|
114
|
+
selfClosing,
|
|
115
|
+
next,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export function* xmlEvents(source) {
|
|
119
|
+
const length = source.length;
|
|
120
|
+
let i = 0;
|
|
121
|
+
while (i < length) {
|
|
122
|
+
const lt = source.indexOf('<', i);
|
|
123
|
+
if (lt === -1) {
|
|
124
|
+
const chunk = source.slice(i);
|
|
125
|
+
if (chunk.length > 0)
|
|
126
|
+
yield { kind: 'text', text: decodeEntities(normalizeLineEndings(chunk)) };
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (lt > i) {
|
|
130
|
+
const chunk = source.slice(i, lt);
|
|
131
|
+
if (chunk.length > 0)
|
|
132
|
+
yield { kind: 'text', text: decodeEntities(normalizeLineEndings(chunk)) };
|
|
133
|
+
}
|
|
134
|
+
const markup = markupAt(source, lt);
|
|
135
|
+
if (markup !== undefined) {
|
|
136
|
+
if (markup.kind === 'cdata') {
|
|
137
|
+
yield { kind: 'text', text: source.slice(markup.contentStart, markup.contentEnd) };
|
|
138
|
+
}
|
|
139
|
+
i = markup.next;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const tag = tagAt(source, lt);
|
|
143
|
+
yield tag.close
|
|
144
|
+
? { kind: 'close', name: tag.name }
|
|
145
|
+
: {
|
|
146
|
+
kind: 'open',
|
|
147
|
+
name: tag.name,
|
|
148
|
+
attrs: parseAttributes(tag.attrSource),
|
|
149
|
+
selfClosing: tag.selfClosing,
|
|
150
|
+
};
|
|
151
|
+
i = tag.next;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function normalizeLineEndings(chunk) {
|
|
155
|
+
if (!chunk.includes('\r'))
|
|
156
|
+
return chunk;
|
|
157
|
+
return chunk.replace(/\r\n?/g, '\n');
|
|
158
|
+
}
|
|
159
|
+
function firstWhitespace(source) {
|
|
160
|
+
for (let i = 0; i < source.length; i++) {
|
|
161
|
+
const code = source.charCodeAt(i);
|
|
162
|
+
if (code === 0x20 || code === 0x09 || code === 0x0a || code === 0x0d)
|
|
163
|
+
return i;
|
|
164
|
+
}
|
|
165
|
+
return -1;
|
|
166
|
+
}
|
|
167
|
+
export function localName(qualified) {
|
|
168
|
+
const colon = qualified.indexOf(':');
|
|
169
|
+
return colon === -1 ? qualified : qualified.slice(colon + 1);
|
|
170
|
+
}
|
|
171
|
+
export function boolPresent(val) {
|
|
172
|
+
return val === undefined || (val !== '0' && val !== 'false');
|
|
173
|
+
}
|
|
174
|
+
export function boolStrict(val) {
|
|
175
|
+
return val === '1' || val === 'true';
|
|
176
|
+
}
|
|
177
|
+
export function boolTristate(val) {
|
|
178
|
+
if (val === '1' || val === 'true')
|
|
179
|
+
return true;
|
|
180
|
+
if (val === '0' || val === 'false')
|
|
181
|
+
return false;
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
export function numInteger(val, min = -Number.MAX_SAFE_INTEGER) {
|
|
185
|
+
const n = parseAttrNumber(val);
|
|
186
|
+
if (n === undefined || !Number.isSafeInteger(n) || n < min)
|
|
187
|
+
return undefined;
|
|
188
|
+
return n;
|
|
189
|
+
}
|
|
190
|
+
export function numFinite(val, min = -Infinity) {
|
|
191
|
+
const n = parseAttrNumber(val);
|
|
192
|
+
if (n === undefined || n < min)
|
|
193
|
+
return undefined;
|
|
194
|
+
return n;
|
|
195
|
+
}
|
|
196
|
+
function parseAttrNumber(val) {
|
|
197
|
+
if (val === undefined || val.trim() === '')
|
|
198
|
+
return undefined;
|
|
199
|
+
const n = Number(val);
|
|
200
|
+
return Number.isFinite(n) ? n : undefined;
|
|
201
|
+
}
|
|
202
|
+
export function coerceNumericLiteral(text) {
|
|
203
|
+
const trimmed = text.trim();
|
|
204
|
+
return /^-?\d+(?:\.\d+)?$/.test(trimmed) ? Number(trimmed) : text;
|
|
205
|
+
}
|
|
206
|
+
export function enumToken(val, isMember) {
|
|
207
|
+
return val !== undefined && isMember(val) ? val : undefined;
|
|
208
|
+
}
|
package/dist/xml/xml.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function escapeAttr(value: string): string;
|
|
|
25
25
|
* `escapeText` runs last and sees no unrepresentable character left, so its guard is a
|
|
26
26
|
* standing proof that the escape was complete rather than a second check of the same thing.
|
|
27
27
|
*
|
|
28
|
-
* Reversed by `decodeSpreadsheetText` in `./xml-
|
|
28
|
+
* Reversed by `decodeSpreadsheetText` in `./xml-scan.ts`, whose single left-to-right pass is what
|
|
29
29
|
* makes the `_x005F_` step above reversible. Change either and read its comment first.
|
|
30
30
|
*/
|
|
31
31
|
export declare function escapeSpreadsheetText(value: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shbernal/ts-xlsx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A TypeScript-first library for reading and writing xlsx (OOXML) spreadsheets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"csv",
|
|
@@ -77,8 +77,7 @@
|
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"prepare": "node scripts/install-hooks.ts",
|
|
80
|
-
"
|
|
81
|
-
"build": "pnpm run clean && tsc -p tsconfig.build.json && tsc -p tsconfig.build.dts.json",
|
|
80
|
+
"build": "node scripts/build.ts",
|
|
82
81
|
"size": "node scripts/size-budget.ts",
|
|
83
82
|
"smoke:dist": "node scripts/smoke-dist.ts",
|
|
84
83
|
"site:prepare": "node www/scripts/sync-docs.ts",
|