@docx-editor.dev/core 2.4.0 → 2.5.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.
Files changed (109) hide show
  1. package/dist/automation.cjs +1 -1
  2. package/dist/automation.d.cts +6 -6
  3. package/dist/automation.d.ts +6 -6
  4. package/dist/automation.js +1 -1
  5. package/dist/binding.cjs +1 -1
  6. package/dist/binding.d.cts +12 -12
  7. package/dist/binding.d.ts +12 -12
  8. package/dist/binding.js +1 -1
  9. package/dist/chunk-2GSRLGUI.cjs +10 -0
  10. package/dist/chunk-2QIA75K3.js +2 -0
  11. package/dist/chunk-32NXPFYL.js +5 -0
  12. package/dist/chunk-3C533HSQ.cjs +18 -0
  13. package/dist/{chunk-YMIMLEX4.cjs → chunk-3FRSOOND.cjs} +1 -1
  14. package/dist/chunk-45FL7KH4.js +1 -0
  15. package/dist/chunk-7GYF33B5.cjs +2 -0
  16. package/dist/chunk-H3DZP4LE.cjs +5 -0
  17. package/dist/chunk-IJ4V3LGV.cjs +2 -0
  18. package/dist/chunk-JDHTCMFA.cjs +2 -0
  19. package/dist/chunk-L2GMLEHX.cjs +14 -0
  20. package/dist/chunk-LJIX4ZDF.js +10 -0
  21. package/dist/chunk-QUZM6LWQ.js +14 -0
  22. package/dist/chunk-T252F4US.js +18 -0
  23. package/dist/chunk-UVIUNAQ6.js +2 -0
  24. package/dist/chunk-YTZIGUXT.js +2 -0
  25. package/dist/{content-control-walk-CbTqHq6O.d.cts → content-control-walk-BeAFh6Xi.d.cts} +1 -1
  26. package/dist/{content-control-walk-D06GijR0.d.ts → content-control-walk-CQp8l6eS.d.ts} +1 -1
  27. package/dist/contracts/editor.d.cts +9 -9
  28. package/dist/contracts/editor.d.ts +9 -9
  29. package/dist/contracts/interaction.d.cts +9 -9
  30. package/dist/contracts/interaction.d.ts +9 -9
  31. package/dist/contracts/modules.d.cts +5 -5
  32. package/dist/contracts/modules.d.ts +5 -5
  33. package/dist/{custom-node-writes-BkMgMXxs.d.ts → custom-node-writes-2clI36T9.d.ts} +22 -7
  34. package/dist/{custom-node-writes-C5YRoPcc.d.cts → custom-node-writes-CIC_-wad.d.cts} +22 -7
  35. package/dist/{editor-DYvC9CZs.d.cts → editor-CUul9IuY.d.cts} +22 -5
  36. package/dist/{editor-D1qHfzOt.d.ts → editor-DIwctMcU.d.ts} +22 -5
  37. package/dist/editor.cjs +1 -1
  38. package/dist/editor.css +32 -0
  39. package/dist/editor.d.cts +24 -24
  40. package/dist/editor.d.ts +24 -24
  41. package/dist/editor.js +1 -1
  42. package/dist/{hf-references-CgEOSw3i.d.cts → hf-references-BPET4tlK.d.cts} +2 -2
  43. package/dist/{hf-references-BdjsQNE_.d.ts → hf-references-CAp1xTv6.d.ts} +2 -2
  44. package/dist/{image-resources-DXvPZvXD.d.cts → image-resources-CSlQmPIm.d.cts} +10 -10
  45. package/dist/{image-resources-BG9DLyW7.d.ts → image-resources-e13t-pgy.d.ts} +10 -10
  46. package/dist/{index-Bb-QAg_f.d.cts → index-8t44iXTY.d.cts} +79 -14
  47. package/dist/{index-DpY3WZuP.d.ts → index-BUsYjxF5.d.ts} +79 -14
  48. package/dist/index.cjs +1 -1
  49. package/dist/index.d.cts +18 -18
  50. package/dist/index.d.ts +18 -18
  51. package/dist/index.js +1 -1
  52. package/dist/layout.cjs +1 -1
  53. package/dist/layout.d.cts +114 -50
  54. package/dist/layout.d.ts +114 -50
  55. package/dist/layout.js +1 -1
  56. package/dist/{note-nodes-C6DLxlvj.d.cts → note-nodes-B2wWES2L.d.cts} +1 -1
  57. package/dist/{note-nodes-BPSTVDMr.d.ts → note-nodes-CZQXU6Fg.d.ts} +1 -1
  58. package/dist/{review-reads-CQmU9Lcl.d.ts → note-properties-BS66XmcC.d.ts} +91 -67
  59. package/dist/{review-reads-CxgN62yp.d.cts → note-properties-Dhqkro--.d.cts} +91 -67
  60. package/dist/{ooxml-package-D_CtywTW.d.ts → ooxml-package-BrxTmTsZ.d.ts} +115 -115
  61. package/dist/{ooxml-package-CR5us6ad.d.cts → ooxml-package-Cmbe_M04.d.cts} +115 -115
  62. package/dist/{ooxml-tree-BU0e3DVi.d.cts → ooxml-tree-CG0odFyi.d.cts} +1 -1
  63. package/dist/{ooxml-tree-BU0e3DVi.d.ts → ooxml-tree-CG0odFyi.d.ts} +1 -1
  64. package/dist/output.cjs +1 -1
  65. package/dist/output.d.cts +7 -7
  66. package/dist/output.d.ts +7 -7
  67. package/dist/output.js +1 -1
  68. package/dist/{protocol-CD7slqvl.d.cts → protocol-B5oSt08P.d.cts} +2 -2
  69. package/dist/{protocol-DsbfgBwA.d.ts → protocol-ooK7PAXz.d.ts} +2 -2
  70. package/dist/{review-support-DgXTIYBW.d.ts → review-support-Bl9sN8cv.d.ts} +47 -3
  71. package/dist/{review-support-BJ-YjGmD.d.cts → review-support-CHuJxHmz.d.cts} +47 -3
  72. package/dist/{revision-projection-DHAkcD_L.d.ts → revision-projection-DRZMzoLD.d.cts} +54 -3
  73. package/dist/{revision-projection-72ZApe-g.d.cts → revision-projection-u4nT52xT.d.ts} +54 -3
  74. package/dist/{semantic-cell-selection-DZtyMXkH.d.ts → semantic-cell-selection-CdNQ-a9-.d.cts} +8 -5
  75. package/dist/{semantic-cell-selection--ezfezTe.d.cts → semantic-cell-selection-Dc-_enhm.d.ts} +8 -5
  76. package/dist/{semantic-interaction-DrgbgKg6.d.ts → semantic-interaction-CCVwyw2A.d.ts} +2 -30
  77. package/dist/{semantic-interaction-2yxdv7q0.d.cts → semantic-interaction-DgaWs-5w.d.cts} +2 -30
  78. package/dist/{semantic-paint-BYjE0Xbl.d.cts → semantic-paint-6iIB4fhx.d.cts} +2 -2
  79. package/dist/{semantic-paint-BedBxkyY.d.ts → semantic-paint-CKIbFkQ7.d.ts} +2 -2
  80. package/dist/{semantic-records-CR5hTqMK.d.ts → semantic-records-B-qbrnp2.d.ts} +107 -9
  81. package/dist/{semantic-records-DSD8WENa.d.cts → semantic-records-Dq8SlCY8.d.cts} +107 -9
  82. package/dist/{shaped-measurer-BL8g4AcW.d.ts → shaped-measurer-BT4FqYe9.d.ts} +1 -1
  83. package/dist/{shaped-measurer-CBOTJTV_.d.cts → shaped-measurer-Dx4llNhK.d.cts} +1 -1
  84. package/dist/store.cjs +1 -1
  85. package/dist/store.d.cts +254 -231
  86. package/dist/store.d.ts +254 -231
  87. package/dist/store.js +1 -1
  88. package/dist/{tree-op-types-8a6xyRCN.d.ts → tree-op-types-CZw9QhWX.d.ts} +219 -219
  89. package/dist/{tree-op-types-EZXbR8bW.d.cts → tree-op-types-DOYNkKqD.d.cts} +219 -219
  90. package/dist/{tree-session-SucW0znF.d.ts → tree-session-CF_EOhTW.d.ts} +14 -8
  91. package/dist/{tree-session-DrMm8Cj2.d.cts → tree-session-CtK3KgFU.d.cts} +14 -8
  92. package/dist/{tree-store-BoM6eXaL.d.ts → tree-store-9TaX-L0V.d.ts} +31 -4
  93. package/dist/{tree-store-UYrGKF_Q.d.cts → tree-store-Jg-q7fyf.d.cts} +31 -4
  94. package/package.json +3 -3
  95. package/dist/chunk-33F6TRXO.js +0 -2
  96. package/dist/chunk-4WWEDTTE.js +0 -2
  97. package/dist/chunk-BS554B6D.cjs +0 -2
  98. package/dist/chunk-DQ5HGUWG.cjs +0 -12
  99. package/dist/chunk-EQO762XH.cjs +0 -10
  100. package/dist/chunk-F6WNPYOM.js +0 -2
  101. package/dist/chunk-FL4GWK76.js +0 -12
  102. package/dist/chunk-GWG5IVVX.cjs +0 -5
  103. package/dist/chunk-IZIL6BAW.cjs +0 -12
  104. package/dist/chunk-LIJPSHRA.js +0 -5
  105. package/dist/chunk-MHDO6HLI.cjs +0 -2
  106. package/dist/chunk-SG7OH2EK.js +0 -12
  107. package/dist/chunk-TCX3PVWR.js +0 -10
  108. package/dist/chunk-YTYKNA6X.cjs +0 -2
  109. package/dist/chunk-ZACHY6OS.js +0 -1
@@ -1,70 +1,6 @@
1
- import { e as OoxmlPart, O as OoxmlNode, a as OoxmlElement } from './ooxml-tree-BU0e3DVi.cjs';
2
- import { O as OoxmlPackage } from './ooxml-package-CR5us6ad.cjs';
3
- import { R as RevisionAddress } from './tree-op-types-EZXbR8bW.cjs';
4
-
5
- /** `w:pos` — where a section's footnotes are laid out. */
6
- type FootnotePosition = 'pageBottom' | 'beneathText' | 'sectEnd' | 'docEnd';
7
- /** `w:pos` for endnotes — only the two document-level placements are legal. */
8
- type EndnotePosition = 'sectEnd' | 'docEnd';
9
- /** `w:numRestart` — when note numbering starts over. `eachPage` needs the reference's page. */
10
- type NoteNumRestart = 'continuous' | 'eachSect' | 'eachPage';
11
- /** Authored subset — only keys present in the file appear. */
12
- interface AuthoredNoteProperties {
13
- readonly pos?: string;
14
- readonly numFmt?: string;
15
- readonly numStart?: number;
16
- readonly numRestart?: string;
17
- }
18
- /** Fully resolved footnote properties (defaults filled). */
19
- interface ResolvedFootnoteProperties {
20
- readonly pos: FootnotePosition;
21
- readonly numFmt: string;
22
- readonly numStart: number;
23
- readonly numRestart: NoteNumRestart;
24
- }
25
- /** Fully resolved endnote properties (defaults filled). */
26
- interface ResolvedEndnoteProperties {
27
- readonly pos: EndnotePosition;
28
- readonly numFmt: string;
29
- readonly numStart: number;
30
- readonly numRestart: NoteNumRestart;
31
- }
32
- /** Word's own footnote defaults, applied where a section declares no `w:footnotePr`. */
33
- declare const DEFAULT_FOOTNOTE_PROPERTIES: ResolvedFootnoteProperties;
34
- /**
35
- * Word-compatible defaults. ECMA-376 says omitted endnote `numFmt` is decimal;
36
- * MS-OE376 / MS-OI29500 document that Word’s default is `lowerRoman` instead.
37
- * Resolved (not authored) — unedited packages still invent nothing on save.
38
- */
39
- declare const DEFAULT_ENDNOTE_PROPERTIES: ResolvedEndnoteProperties;
40
- /** Parse authored CT_FtnProps / CT_EdnProps without inventing defaults. */
41
- declare function parseAuthoredNoteProperties(propsNode: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
42
- /** Authored footnotePr on a sectPr node. */
43
- declare function authoredFootnotePropertiesFromSectPr(sectPr: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
44
- /** Authored endnotePr on a sectPr node. */
45
- declare function authoredEndnotePropertiesFromSectPr(sectPr: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
46
- /** Locate settings.xml via the main document relationship when present. */
47
- declare function settingsPartOf(pkg: OoxmlPackage): OoxmlPart | null;
48
- /** Authored document-level footnotePr from settings. */
49
- declare function authoredDocumentFootnoteProperties(settings: OoxmlPart | null | undefined): AuthoredNoteProperties | undefined;
50
- /** Authored document-level endnotePr from settings. */
51
- declare function authoredDocumentEndnoteProperties(settings: OoxmlPart | null | undefined): AuthoredNoteProperties | undefined;
52
- /**
53
- * Resolve footnote properties: section → document → defaults.
54
- * Illegal position strings fall through to the next layer / default.
55
- */
56
- declare function resolveFootnoteProperties(section?: AuthoredNoteProperties, document?: AuthoredNoteProperties): ResolvedFootnoteProperties;
57
- /**
58
- * Resolve endnote properties: section → document → defaults.
59
- * `pageBottom` is never a legal endnote position — falls back.
60
- */
61
- declare function resolveEndnoteProperties(section?: AuthoredNoteProperties, document?: AuthoredNoteProperties): ResolvedEndnoteProperties;
62
- /** Validate an authored endnote position write — refuse `pageBottom`. */
63
- declare function isLegalEndnotePosition(pos: string): pos is EndnotePosition;
64
- /** Validate an authored footnote position write. */
65
- declare function isLegalFootnotePosition(pos: string): pos is FootnotePosition;
66
- /** Whether a file-supplied string is a legal `w:numRestart` value. Narrows the type. */
67
- declare function isLegalNumRestart(value: string): value is NoteNumRestart;
1
+ import { a as OoxmlElement, e as OoxmlPart, O as OoxmlNode } from './ooxml-tree-CG0odFyi.cjs';
2
+ import { R as RevisionAddress } from './tree-op-types-DOYNkKqD.cjs';
3
+ import { O as OoxmlPackage } from './ooxml-package-Cmbe_M04.cjs';
68
4
 
69
5
  /** The `w15` namespace: `commentsExtended.xml` — thread parent and resolved state. */
70
6
  declare const W15_NAMESPACE_URI = "http://schemas.microsoft.com/office/word/2012/wordml";
@@ -196,12 +132,34 @@ interface ReviewRevisionItem {
196
132
  /** The words a replacement removes. Empty for every other kind. */
197
133
  readonly replacedText: string;
198
134
  readonly revisionKind: ReviewRevisionKind;
135
+ /**
136
+ * WHICH decision a `paragraphMark` records, absent for every other kind.
137
+ *
138
+ * `EG_ParaRPrTrackChanges` is `ins? del? moveFrom? moveTo?`, and the four say opposite
139
+ * things about the same break: one proposes it, another proposes taking it away. Collapsing
140
+ * them into the single kind lost that, and a card then described a deleted break as an
141
+ * inserted one — the reverse of what Accept on that card does.
142
+ */
143
+ readonly markDirection?: 'insert' | 'delete' | 'moveFrom' | 'moveTo';
199
144
  readonly author: string;
200
145
  readonly date?: string;
201
146
  /** Text the revision covers, for the card summary. Empty for changes with no characters. */
202
147
  readonly text: string;
203
148
  /** Every site this decision touches, in document order. */
204
149
  readonly ranges: readonly ReviewRange[];
150
+ /**
151
+ * How deeply this change is NESTED inside other changes, 0 for an unenclosed one.
152
+ *
153
+ * Revisions nest for real, and OOXML has no other way to say what happened: `w:ins` wrapping
154
+ * `w:del` is content one reviewer added and another struck. Both stay pending, because each
155
+ * author has to be answered separately, so both are cards — over one identical range.
156
+ *
157
+ * A range therefore cannot say which change a position is "in", and this is what settles it.
158
+ * Word treats the innermost change as the operative one: the words are struck on the page
159
+ * because of the deletion, and accepting the change under them performs that deletion. So the
160
+ * deepest card wins the caret, and the one enclosing it stays listed and reachable.
161
+ */
162
+ readonly nesting: number;
205
163
  /**
206
164
  * How many leading `ranges` are the STRUCK half of a replacement.
207
165
  *
@@ -347,6 +305,8 @@ interface LinkableReviewItem {
347
305
  readonly parentRevisionId?: string;
348
306
  readonly replyIds?: readonly string[];
349
307
  readonly orphaned?: boolean;
308
+ /** How deeply a revision is nested; absent on the kinds that cannot nest. */
309
+ readonly nesting?: number;
350
310
  }
351
311
  /**
352
312
  * Attach each comment that answers a tracked change to the change it answers.
@@ -405,4 +365,68 @@ declare function reviewItemRanges(item: ReviewItem): readonly ReviewRange[];
405
365
  /** The range an item is anchored at — where its card belongs and how it sorts. */
406
366
  declare function firstReviewRange(item: ReviewItem): ReviewRange | null;
407
367
 
368
+ /** `w:pos` — where a section's footnotes are laid out. */
369
+ type FootnotePosition = 'pageBottom' | 'beneathText' | 'sectEnd' | 'docEnd';
370
+ /** `w:pos` for endnotes — only the two document-level placements are legal. */
371
+ type EndnotePosition = 'sectEnd' | 'docEnd';
372
+ /** `w:numRestart` — when note numbering starts over. `eachPage` needs the reference's page. */
373
+ type NoteNumRestart = 'continuous' | 'eachSect' | 'eachPage';
374
+ /** Authored subset — only keys present in the file appear. */
375
+ interface AuthoredNoteProperties {
376
+ readonly pos?: string;
377
+ readonly numFmt?: string;
378
+ readonly numStart?: number;
379
+ readonly numRestart?: string;
380
+ }
381
+ /** Fully resolved footnote properties (defaults filled). */
382
+ interface ResolvedFootnoteProperties {
383
+ readonly pos: FootnotePosition;
384
+ readonly numFmt: string;
385
+ readonly numStart: number;
386
+ readonly numRestart: NoteNumRestart;
387
+ }
388
+ /** Fully resolved endnote properties (defaults filled). */
389
+ interface ResolvedEndnoteProperties {
390
+ readonly pos: EndnotePosition;
391
+ readonly numFmt: string;
392
+ readonly numStart: number;
393
+ readonly numRestart: NoteNumRestart;
394
+ }
395
+ /** Word's own footnote defaults, applied where a section declares no `w:footnotePr`. */
396
+ declare const DEFAULT_FOOTNOTE_PROPERTIES: ResolvedFootnoteProperties;
397
+ /**
398
+ * Word-compatible defaults. ECMA-376 says omitted endnote `numFmt` is decimal;
399
+ * MS-OE376 / MS-OI29500 document that Word’s default is `lowerRoman` instead.
400
+ * Resolved (not authored) — unedited packages still invent nothing on save.
401
+ */
402
+ declare const DEFAULT_ENDNOTE_PROPERTIES: ResolvedEndnoteProperties;
403
+ /** Parse authored CT_FtnProps / CT_EdnProps without inventing defaults. */
404
+ declare function parseAuthoredNoteProperties(propsNode: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
405
+ /** Authored footnotePr on a sectPr node. */
406
+ declare function authoredFootnotePropertiesFromSectPr(sectPr: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
407
+ /** Authored endnotePr on a sectPr node. */
408
+ declare function authoredEndnotePropertiesFromSectPr(sectPr: OoxmlNode | null | undefined): AuthoredNoteProperties | undefined;
409
+ /** Locate settings.xml via the main document relationship when present. */
410
+ declare function settingsPartOf(pkg: OoxmlPackage): OoxmlPart | null;
411
+ /** Authored document-level footnotePr from settings. */
412
+ declare function authoredDocumentFootnoteProperties(settings: OoxmlPart | null | undefined): AuthoredNoteProperties | undefined;
413
+ /** Authored document-level endnotePr from settings. */
414
+ declare function authoredDocumentEndnoteProperties(settings: OoxmlPart | null | undefined): AuthoredNoteProperties | undefined;
415
+ /**
416
+ * Resolve footnote properties: section → document → defaults.
417
+ * Illegal position strings fall through to the next layer / default.
418
+ */
419
+ declare function resolveFootnoteProperties(section?: AuthoredNoteProperties, document?: AuthoredNoteProperties): ResolvedFootnoteProperties;
420
+ /**
421
+ * Resolve endnote properties: section → document → defaults.
422
+ * `pageBottom` is never a legal endnote position — falls back.
423
+ */
424
+ declare function resolveEndnoteProperties(section?: AuthoredNoteProperties, document?: AuthoredNoteProperties): ResolvedEndnoteProperties;
425
+ /** Validate an authored endnote position write — refuse `pageBottom`. */
426
+ declare function isLegalEndnotePosition(pos: string): pos is EndnotePosition;
427
+ /** Validate an authored footnote position write. */
428
+ declare function isLegalFootnotePosition(pos: string): pos is FootnotePosition;
429
+ /** Whether a file-supplied string is a legal `w:numRestart` value. Narrows the type. */
430
+ declare function isLegalNumRestart(value: string): value is NoteNumRestart;
431
+
408
432
  export { type AuthoredNoteProperties as A, isLegalEndnotePosition as B, type CommentAnchor as C, DEFAULT_ENDNOTE_PROPERTIES as D, type EndnotePosition as E, type FootnotePosition as F, isLegalFootnotePosition as G, isLegalNumRestart as H, linkRevisionReplies as I, parseAuthoredNoteProperties as J, resolveEndnoteProperties as K, type LinkableReviewItem as L, resolveFootnoteProperties as M, type NoteNumRestart as N, reviewItemKey as O, reviewItemRanges as P, revisionItemsOf as Q, type ResolvedFootnoteProperties as R, settingsPartOf as S, threadStateOfPart as T, W15_NAMESPACE_URI as W, type ResolvedEndnoteProperties as a, type CommentPosition as b, type CommentRecord as c, type CommentThreadState as d, DEFAULT_FOOTNOTE_PROPERTIES as e, type ReviewCommentItem as f, type ReviewItem as g, type ReviewModelInput as h, type ReviewPosition as i, type ReviewRange as j, type ReviewRevisionItem as k, type ReviewRevisionKind as l, authoredDocumentEndnoteProperties as m, authoredDocumentFootnoteProperties as n, authoredEndnotePropertiesFromSectPr as o, paragraphOrderOfPart as p, authoredFootnotePropertiesFromSectPr as q, collectReviewItems as r, commentAnchorsOfStory as s, commentBodyText as t, commentInitials as u, commentItemsOf as v, commentsOfPart as w, deepParagraphOrderOfPart as x, firstReviewRange as y, hasAnyComment as z };
@@ -1,4 +1,44 @@
1
- import { e as OoxmlPart, X as XmlLimits, n as OoxmlReadRejection } from './ooxml-tree-BU0e3DVi.js';
1
+ import { e as OoxmlPart, X as XmlLimits, n as OoxmlReadRejection } from './ooxml-tree-CG0odFyi.js';
2
+
3
+ /**
4
+ * Why a zip was refused at the trust boundary.
5
+ *
6
+ * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
7
+ * an entry with `..` or a leading `/` is rejected rather than normalized.
8
+ */
9
+ type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
10
+ /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
11
+ interface ZipLimits {
12
+ readonly maxEntries: number;
13
+ /** Max total UNCOMPRESSED bytes across the archive. */
14
+ readonly maxTotalBytes: number;
15
+ /** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
16
+ readonly maxRatio?: number;
17
+ }
18
+ /** The archive caps in force when a host configures none. Conservative and finite. */
19
+ declare const DEFAULT_ZIP_LIMITS: ZipLimits;
20
+ /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
21
+ type ZipReadResult = {
22
+ readonly ok: true;
23
+ readonly entries: ReadonlyMap<string, Uint8Array>;
24
+ } | {
25
+ readonly ok: false;
26
+ readonly reason: ZipRejection;
27
+ readonly detail?: string;
28
+ };
29
+ /**
30
+ * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count,
31
+ * compression-ratio, and total-uncompressed-size limits are enforced BEFORE each
32
+ * entry is decompressed (via fflate's pre-inflation filter), so a zip bomb or a
33
+ * traversal name is rejected without ever being inflated. Keys are canonical part
34
+ * names.
35
+ */
36
+ declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
37
+ /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
38
+ * is re-validated through the OPC normalization profile before writing, so a
39
+ * traversal/encoded/normalized-alias name from an untrusted serialized model can
40
+ * never be smuggled into a ZIP entry (write-side path-traversal guard). */
41
+ declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
2
42
 
3
43
  /**
4
44
  * Why a part or relationship name was refused.
@@ -56,91 +96,6 @@ declare function resolveInternalTarget(ownerPartName: string, rawTarget: string)
56
96
  */
57
97
  declare function validateExternalTarget(raw: string): NameResult;
58
98
 
59
- /** One `<Default>`: a file extension mapped to a content type. */
60
- interface DefaultRecord {
61
- readonly extension: string;
62
- readonly contentType: string;
63
- readonly order: number;
64
- }
65
- /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
66
- interface OverrideRecord {
67
- readonly partName: string;
68
- readonly contentType: string;
69
- readonly order: number;
70
- }
71
- /**
72
- * The authored `[Content_Types].xml` records, in significant order.
73
- *
74
- * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
75
- * part of what a lossless save re-emits.
76
- */
77
- interface ContentTypeRecords {
78
- readonly defaults: readonly DefaultRecord[];
79
- readonly overrides: readonly OverrideRecord[];
80
- }
81
- /**
82
- * Why content-type records could not be indexed.
83
- *
84
- * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
85
- * invalid MIME syntax are refused rather than resolved by picking one.
86
- */
87
- type ContentTypeError = {
88
- readonly code: 'invalid-mime';
89
- readonly value: string;
90
- } | {
91
- readonly code: 'conflicting-default';
92
- readonly extension: string;
93
- } | {
94
- readonly code: 'duplicate-override';
95
- readonly partName: string;
96
- } | {
97
- readonly code: 'invalid-override-name';
98
- readonly partName: string;
99
- } | {
100
- readonly code: 'too-many-records';
101
- readonly limit: number;
102
- };
103
- /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
104
- declare function isValidMime(value: string): boolean;
105
- /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
106
- declare function extensionKey(extension: string): string;
107
- /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
108
- interface ContentTypeIndex {
109
- /** ext key -> single MIME (identical duplicates collapsed). */
110
- readonly defaults: ReadonlyMap<string, string>;
111
- /** case-folded part name -> MIME. */
112
- readonly overrides: ReadonlyMap<string, string>;
113
- }
114
- /** The built index, or the conflict that made it impossible. */
115
- type IndexResult = {
116
- readonly ok: true;
117
- readonly index: ContentTypeIndex;
118
- } | {
119
- readonly ok: false;
120
- readonly error: ContentTypeError;
121
- };
122
- /**
123
- * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
124
- * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
125
- */
126
- declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
127
- /**
128
- * A part's content type, or why it has none.
129
- *
130
- * An orphan record never determines a part's type — a Default with no matching part is preserved
131
- * inertly rather than applied.
132
- */
133
- type ResolveResult = {
134
- readonly ok: true;
135
- readonly contentType: string;
136
- readonly source: 'override' | 'default';
137
- } | {
138
- readonly ok: false;
139
- readonly reason: 'unknown';
140
- };
141
- /** Resolve a part's content type: Override wins over Default; else unknown. */
142
- declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
143
-
144
99
  /** OOXML image relationship type for embedded or linked media parts. */
145
100
  declare const IMAGE_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
146
101
  /**
@@ -223,45 +178,90 @@ type ImageRelationshipResolution = {
223
178
  */
224
179
  declare function resolveImageRelationship(records: readonly RelationshipRecord[] | undefined, ownerPart: string, relationshipId: string): ImageRelationshipResolution;
225
180
 
181
+ /** One `<Default>`: a file extension mapped to a content type. */
182
+ interface DefaultRecord {
183
+ readonly extension: string;
184
+ readonly contentType: string;
185
+ readonly order: number;
186
+ }
187
+ /** One `<Override>`: a specific part name mapped to a content type. Beats any Default. */
188
+ interface OverrideRecord {
189
+ readonly partName: string;
190
+ readonly contentType: string;
191
+ readonly order: number;
192
+ }
226
193
  /**
227
- * Why a zip was refused at the trust boundary.
194
+ * The authored `[Content_Types].xml` records, in significant order.
228
195
  *
229
- * `too-large` and `too-many-entries` are the zip-bomb guards; `bad-name` catches path traversal —
230
- * an entry with `..` or a leading `/` is rejected rather than normalized.
196
+ * Retained rather than collapsed into a lookup, because the file's lexical form and ordering are
197
+ * part of what a lossless save re-emits.
231
198
  */
232
- type ZipRejection = 'too-many-entries' | 'too-large' | 'bad-name' | 'inflate-error';
233
- /** Archive caps: entry count, total decompressed bytes, and the decompression ratio. */
234
- interface ZipLimits {
235
- readonly maxEntries: number;
236
- /** Max total UNCOMPRESSED bytes across the archive. */
237
- readonly maxTotalBytes: number;
238
- /** Max per-entry uncompressed:compressed ratio (zip-bomb guard). */
239
- readonly maxRatio?: number;
199
+ interface ContentTypeRecords {
200
+ readonly defaults: readonly DefaultRecord[];
201
+ readonly overrides: readonly OverrideRecord[];
240
202
  }
241
- /** The archive caps in force when a host configures none. Conservative and finite. */
242
- declare const DEFAULT_ZIP_LIMITS: ZipLimits;
243
- /** The read entries, or the typed refusal. Never throws — the bytes are untrusted. */
244
- type ZipReadResult = {
203
+ /**
204
+ * Why content-type records could not be indexed.
205
+ *
206
+ * All fail CLOSED: conflicting Defaults on one extension, duplicate normalized Override names, or
207
+ * invalid MIME syntax are refused rather than resolved by picking one.
208
+ */
209
+ type ContentTypeError = {
210
+ readonly code: 'invalid-mime';
211
+ readonly value: string;
212
+ } | {
213
+ readonly code: 'conflicting-default';
214
+ readonly extension: string;
215
+ } | {
216
+ readonly code: 'duplicate-override';
217
+ readonly partName: string;
218
+ } | {
219
+ readonly code: 'invalid-override-name';
220
+ readonly partName: string;
221
+ } | {
222
+ readonly code: 'too-many-records';
223
+ readonly limit: number;
224
+ };
225
+ /** Whether a string is syntactically a MIME type. Syntax only — no registry lookup. */
226
+ declare function isValidMime(value: string): boolean;
227
+ /** ASCII-case-insensitive extension key (leading dot removed; ASCII-only fold). */
228
+ declare function extensionKey(extension: string): string;
229
+ /** The resolved lookup: Override by case-folded part name, Default by case-insensitive extension. */
230
+ interface ContentTypeIndex {
231
+ /** ext key -> single MIME (identical duplicates collapsed). */
232
+ readonly defaults: ReadonlyMap<string, string>;
233
+ /** case-folded part name -> MIME. */
234
+ readonly overrides: ReadonlyMap<string, string>;
235
+ }
236
+ /** The built index, or the conflict that made it impossible. */
237
+ type IndexResult = {
245
238
  readonly ok: true;
246
- readonly entries: ReadonlyMap<string, Uint8Array>;
239
+ readonly index: ContentTypeIndex;
247
240
  } | {
248
241
  readonly ok: false;
249
- readonly reason: ZipRejection;
250
- readonly detail?: string;
242
+ readonly error: ContentTypeError;
251
243
  };
252
244
  /**
253
- * Inflate a ZIP archive with bounds + OPC name normalization. Entry name, count,
254
- * compression-ratio, and total-uncompressed-size limits are enforced BEFORE each
255
- * entry is decompressed (via fflate's pre-inflation filter), so a zip bomb or a
256
- * traversal name is rejected without ever being inflated. Keys are canonical part
257
- * names.
245
+ * Build a resolved content-type index, failing closed on conflict/duplicate/MIME
246
+ * errors. `maxRecords` bounds the combined record count (N/N+1 gate).
258
247
  */
259
- declare function readZip(bytes: Uint8Array, limits?: ZipLimits): ZipReadResult;
260
- /** Deflate a set of canonical-part-name -> bytes into a ZIP archive. Every part name
261
- * is re-validated through the OPC normalization profile before writing, so a
262
- * traversal/encoded/normalized-alias name from an untrusted serialized model can
263
- * never be smuggled into a ZIP entry (write-side path-traversal guard). */
264
- declare function writeZip(entries: ReadonlyMap<string, Uint8Array>): Uint8Array;
248
+ declare function buildContentTypeIndex(records: ContentTypeRecords, maxRecords?: number): IndexResult;
249
+ /**
250
+ * A part's content type, or why it has none.
251
+ *
252
+ * An orphan record never determines a part's type — a Default with no matching part is preserved
253
+ * inertly rather than applied.
254
+ */
255
+ type ResolveResult = {
256
+ readonly ok: true;
257
+ readonly contentType: string;
258
+ readonly source: 'override' | 'default';
259
+ } | {
260
+ readonly ok: false;
261
+ readonly reason: 'unknown';
262
+ };
263
+ /** Resolve a part's content type: Override wins over Default; else unknown. */
264
+ declare function resolveContentType(index: ContentTypeIndex, partName: string): ResolveResult;
265
265
 
266
266
  /** Caps applied while loading a package: zip, XML, part count and relationship count. */
267
267
  interface OoxmlPackageLimits {