@stll/folio-core 0.3.1 → 0.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 (120) hide show
  1. package/dist/ai-edits/apply.d.ts +3 -9
  2. package/dist/ai-edits/apply.js +94 -14
  3. package/dist/ai-edits/blockRange.d.ts +33 -0
  4. package/dist/ai-edits/blockRange.js +58 -0
  5. package/dist/ai-edits/headless.d.ts +35 -5
  6. package/dist/ai-edits/headless.js +92 -22
  7. package/dist/ai-edits/index.d.ts +5 -3
  8. package/dist/ai-edits/index.js +3 -2
  9. package/dist/ai-edits/snapshot.d.ts +14 -2
  10. package/dist/ai-edits/snapshot.js +12 -1
  11. package/dist/ai-edits/types.d.ts +42 -3
  12. package/dist/compat/eigenpal.d.ts +3 -2
  13. package/dist/compat/eigenpal.js +6 -5
  14. package/dist/controller/layoutPipeline.d.ts +1 -0
  15. package/dist/controller/layoutPipeline.js +35 -115
  16. package/dist/controller/layoutScheduler.d.ts +2 -1
  17. package/dist/controller/layoutScheduler.js +6 -0
  18. package/dist/document-operations.d.ts +122 -0
  19. package/dist/document-operations.js +575 -0
  20. package/dist/docx/blockContentParser.js +17 -7
  21. package/dist/docx/encryption/agileDecryption.d.ts +6 -0
  22. package/dist/docx/encryption/agileDecryption.js +209 -0
  23. package/dist/docx/encryption/compoundFile.d.ts +20 -0
  24. package/dist/docx/encryption/compoundFile.js +251 -0
  25. package/dist/docx/encryption/containerFormat.d.ts +15 -0
  26. package/dist/docx/encryption/containerFormat.js +40 -0
  27. package/dist/docx/encryption/cryptoBytes.d.ts +11 -0
  28. package/dist/docx/encryption/cryptoBytes.js +55 -0
  29. package/dist/docx/encryption/encryptionInfo.d.ts +32 -0
  30. package/dist/docx/encryption/encryptionInfo.js +128 -0
  31. package/dist/docx/encryption/errors.d.ts +18 -0
  32. package/dist/docx/encryption/errors.js +13 -0
  33. package/dist/docx/encryption/index.d.ts +4 -0
  34. package/dist/docx/encryption/index.js +4 -0
  35. package/dist/docx/encryption/openEncryptedDocx.d.ts +28 -0
  36. package/dist/docx/encryption/openEncryptedDocx.js +65 -0
  37. package/dist/docx/footnoteParser.d.ts +1 -17
  38. package/dist/docx/footnoteParser.js +1 -27
  39. package/dist/docx/groupDrawingParser.d.ts +8 -0
  40. package/dist/docx/groupDrawingParser.js +131 -0
  41. package/dist/docx/index.d.ts +3 -1
  42. package/dist/docx/index.js +3 -1
  43. package/dist/docx/numberingParser.d.ts +3 -1
  44. package/dist/docx/numberingParser.js +8 -2
  45. package/dist/docx/paragraphParser.js +9 -3
  46. package/dist/docx/parser.d.ts +4 -5
  47. package/dist/docx/parser.js +8 -2
  48. package/dist/docx/runParser.js +8 -1
  49. package/dist/docx/selectiveXmlPatch.js +4 -10
  50. package/dist/docx/serializer/numberingSerializer.js +3 -1
  51. package/dist/docx/settingsParser.d.ts +6 -3
  52. package/dist/docx/settingsParser.js +2 -0
  53. package/dist/docx/unzip.d.ts +7 -5
  54. package/dist/docx/unzip.js +8 -2
  55. package/dist/docx/xmlParser.js +11 -4
  56. package/dist/index.d.ts +3 -2
  57. package/dist/index.js +6 -5
  58. package/dist/layout-bridge/convert/footnoteLayout.d.ts +37 -1
  59. package/dist/layout-bridge/convert/footnoteLayout.js +138 -14
  60. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +6 -8
  61. package/dist/layout-bridge/convert/headerFooterLayout.js +21 -13
  62. package/dist/layout-bridge/convert/toFlowBlocks.js +58 -19
  63. package/dist/layout-engine/index.d.ts +6 -5
  64. package/dist/layout-engine/index.js +116 -27
  65. package/dist/layout-engine/keep-together.d.ts +13 -8
  66. package/dist/layout-engine/keep-together.js +40 -25
  67. package/dist/layout-engine/layoutInstrumentation.d.ts +11 -1
  68. package/dist/layout-engine/layoutInstrumentation.js +10 -1
  69. package/dist/layout-engine/measure/measureBlocks.js +43 -19
  70. package/dist/layout-engine/measure/measureParagraph.js +91 -14
  71. package/dist/layout-engine/paginator.d.ts +2 -1
  72. package/dist/layout-engine/paginator.js +9 -3
  73. package/dist/layout-engine/textBoxGroup.d.ts +7 -0
  74. package/dist/layout-engine/textBoxGroup.js +8 -0
  75. package/dist/layout-engine/types.d.ts +33 -9
  76. package/dist/layout-engine/types.js +20 -2
  77. package/dist/layout-painter/renderPage.d.ts +15 -1
  78. package/dist/layout-painter/renderPage.js +29 -12
  79. package/dist/layout-painter/renderParagraph.js +44 -9
  80. package/dist/layout-painter/renderTable.js +27 -7
  81. package/dist/managers/DocumentLoaderManager.d.ts +3 -1
  82. package/dist/managers/DocumentLoaderManager.js +13 -5
  83. package/dist/managers/TableSelectionManager.js +1 -1
  84. package/dist/model.js +1 -1
  85. package/dist/paged-layout/pageText.d.ts +14 -0
  86. package/dist/paged-layout/pageText.js +21 -0
  87. package/dist/prosemirror/attrs/index.js +3 -0
  88. package/dist/prosemirror/commands/comments.js +75 -5
  89. package/dist/prosemirror/commands/hyperlink.js +4 -2
  90. package/dist/prosemirror/commands/image.js +2 -1
  91. package/dist/prosemirror/commands/index.js +1 -1
  92. package/dist/prosemirror/commands/propertyChangeScope.d.ts +68 -0
  93. package/dist/prosemirror/commands/propertyChangeScope.js +242 -0
  94. package/dist/prosemirror/conversion/fromProseDoc.js +21 -5
  95. package/dist/prosemirror/conversion/toProseDoc.js +43 -15
  96. package/dist/prosemirror/extensions/core/ParagraphExtension.js +3 -0
  97. package/dist/prosemirror/extensions/features/ListExtension.js +6 -0
  98. package/dist/prosemirror/extensions/nodes/TableExtension.js +12 -11
  99. package/dist/prosemirror/findReplaceSelection.js +2 -1
  100. package/dist/prosemirror/index.js +1 -1
  101. package/dist/prosemirror/insertOperations.js +1 -1
  102. package/dist/prosemirror/schema/nodes.d.ts +14 -7
  103. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  104. package/dist/prosemirror/utils/tabCalculator.js +4 -2
  105. package/dist/redline.d.ts +20 -0
  106. package/dist/redline.js +127 -0
  107. package/dist/server.d.ts +7 -3
  108. package/dist/server.js +6 -2
  109. package/dist/symbols.d.ts +35 -0
  110. package/dist/symbols.js +512 -0
  111. package/dist/utils/clipboard.js +3 -3
  112. package/dist/utils/fontLoader.js +3 -0
  113. package/dist/utils/fontResolver.js +65 -1
  114. package/dist/utils/zoom.d.ts +21 -0
  115. package/dist/utils/zoom.js +21 -0
  116. package/dist/version-comparison.d.ts +92 -0
  117. package/dist/version-comparison.js +436 -0
  118. package/package.json +7 -3
  119. package/dist/paged-layout/headerFooterMargins.d.ts +0 -73
  120. package/dist/paged-layout/headerFooterMargins.js +0 -120
@@ -0,0 +1,575 @@
1
+ import { applyFolioAIEditOperations, previewFolioAIEditOperations } from "./ai-edits/apply.js";
2
+ import { TaggedError } from "better-result";
3
+ //#region src/document-operations.ts
4
+ const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION = 1;
5
+ const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
6
+ "replaceInBlock",
7
+ "replaceRange",
8
+ "commentOnRange",
9
+ "formatRange",
10
+ "insertAfterBlock",
11
+ "insertBeforeBlock",
12
+ "replaceBlock",
13
+ "deleteBlock",
14
+ "commentOnBlock",
15
+ "insertSignatureTable"
16
+ ]);
17
+ const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze(["direct", "tracked-changes"]);
18
+ const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze(["main"]);
19
+ const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS = Object.freeze(["blockTextHash"]);
20
+ const FOLIO_DOCUMENT_OPERATION_BATCH_MODES = Object.freeze(["best-effort", "atomic"]);
21
+ const DIRECT_AND_TRACKED_MODES = FOLIO_DOCUMENT_OPERATION_MODES;
22
+ const DIRECT_ONLY_MODES = Object.freeze(["direct"]);
23
+ const FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE = Object.freeze({
24
+ replaceInBlock: DIRECT_AND_TRACKED_MODES,
25
+ replaceRange: DIRECT_AND_TRACKED_MODES,
26
+ commentOnRange: DIRECT_AND_TRACKED_MODES,
27
+ formatRange: DIRECT_ONLY_MODES,
28
+ insertAfterBlock: DIRECT_AND_TRACKED_MODES,
29
+ insertBeforeBlock: DIRECT_AND_TRACKED_MODES,
30
+ replaceBlock: DIRECT_AND_TRACKED_MODES,
31
+ deleteBlock: DIRECT_AND_TRACKED_MODES,
32
+ commentOnBlock: DIRECT_AND_TRACKED_MODES,
33
+ insertSignatureTable: DIRECT_ONLY_MODES
34
+ });
35
+ const DOCUMENT_OPERATION_CAPABILITIES = Object.freeze({
36
+ version: 1,
37
+ operationTypes: FOLIO_DOCUMENT_OPERATION_TYPES,
38
+ modes: FOLIO_DOCUMENT_OPERATION_MODES,
39
+ modesByOperationType: FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE,
40
+ batchModes: FOLIO_DOCUMENT_OPERATION_BATCH_MODES,
41
+ dryRun: true,
42
+ preconditions: FOLIO_DOCUMENT_OPERATION_PRECONDITIONS,
43
+ stories: FOLIO_DOCUMENT_OPERATION_STORIES
44
+ });
45
+ const getFolioDocumentOperationCapabilities = () => DOCUMENT_OPERATION_CAPABILITIES;
46
+ const includesDocumentOperationMode = (supportedModes, mode) => supportedModes.includes(mode);
47
+ const isFolioDocumentOperationModeSupported = (operationType, mode) => {
48
+ const supportedModes = FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE[operationType];
49
+ if (supportedModes === void 0) return false;
50
+ return includesDocumentOperationMode(supportedModes, mode);
51
+ };
52
+ const isSupportedFolioDocumentOperationVersion = (value) => value === 1;
53
+ var UnsupportedFolioDocumentOperationVersionError = class extends TaggedError("UnsupportedFolioDocumentOperationVersionError")() {};
54
+ var InvalidFolioDocumentOperationBatchError = class extends TaggedError("InvalidFolioDocumentOperationBatchError")() {};
55
+ const assertSupportedFolioDocumentOperationVersion = (value) => {
56
+ if (isSupportedFolioDocumentOperationVersion(value)) return value;
57
+ throw new UnsupportedFolioDocumentOperationVersionError({
58
+ message: "Unsupported document operation contract version.",
59
+ receivedVersion: value
60
+ });
61
+ };
62
+ const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
63
+ const invalidBatch = (path, reason) => {
64
+ throw new InvalidFolioDocumentOperationBatchError({
65
+ message: `Invalid document operation batch at ${path}: ${reason}.`,
66
+ path,
67
+ reason
68
+ });
69
+ };
70
+ const assertAllowedKeys = (value, path, allowedKeys) => {
71
+ const unexpected = Object.keys(value).find((key) => !allowedKeys.includes(key));
72
+ if (unexpected !== void 0) invalidBatch(`${path}.${unexpected}`, "unexpected property");
73
+ };
74
+ const readString = (value, key, path) => {
75
+ const candidate = value[key];
76
+ if (typeof candidate === "string") return candidate;
77
+ return invalidBatch(`${path}.${key}`, "expected a string");
78
+ };
79
+ const readOptionalString = (value, key, path) => {
80
+ const candidate = value[key];
81
+ if (candidate === void 0) return;
82
+ if (typeof candidate === "string") return candidate;
83
+ return invalidBatch(`${path}.${key}`, "expected a string when provided");
84
+ };
85
+ const readOptionalBoolean = (value, key, path) => {
86
+ const candidate = value[key];
87
+ if (candidate === void 0) return;
88
+ if (typeof candidate === "boolean") return candidate;
89
+ return invalidBatch(`${path}.${key}`, "expected a boolean when provided");
90
+ };
91
+ const readNonNegativeInteger = (value, key, path) => {
92
+ const candidate = value[key];
93
+ if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 0) return candidate;
94
+ return invalidBatch(`${path}.${key}`, "expected a non-negative integer");
95
+ };
96
+ const readTextRange = (value, path) => {
97
+ const candidate = value["range"];
98
+ const rangePath = `${path}.range`;
99
+ if (!isPlainObject(candidate)) return invalidBatch(rangePath, "expected an object");
100
+ assertAllowedKeys(candidate, rangePath, [
101
+ "type",
102
+ "story",
103
+ "blockId",
104
+ "startOffset",
105
+ "endOffset",
106
+ "selectedTextHash"
107
+ ]);
108
+ if (candidate["type"] !== "textRange") return invalidBatch(`${rangePath}.type`, "expected \"textRange\"");
109
+ if (candidate["story"] !== "main") return invalidBatch(`${rangePath}.story`, "expected \"main\"");
110
+ const blockId = readString(candidate, "blockId", rangePath);
111
+ if (blockId.length === 0) return invalidBatch(`${rangePath}.blockId`, "expected a non-empty string");
112
+ const startOffset = readNonNegativeInteger(candidate, "startOffset", rangePath);
113
+ const endOffset = readNonNegativeInteger(candidate, "endOffset", rangePath);
114
+ if (endOffset <= startOffset) return invalidBatch(`${rangePath}.endOffset`, "expected a value greater than startOffset");
115
+ const selectedTextHash = readString(candidate, "selectedTextHash", rangePath);
116
+ if (!/^h[0-9a-z]+$/.test(selectedTextHash)) return invalidBatch(`${rangePath}.selectedTextHash`, "expected a normalized text hash");
117
+ return {
118
+ type: "textRange",
119
+ story: "main",
120
+ blockId,
121
+ startOffset,
122
+ endOffset,
123
+ selectedTextHash
124
+ };
125
+ };
126
+ const readInlineFormatting = (value, path) => {
127
+ const candidate = value["formatting"];
128
+ const formattingPath = `${path}.formatting`;
129
+ if (!isPlainObject(candidate)) return invalidBatch(formattingPath, "expected an object");
130
+ assertAllowedKeys(candidate, formattingPath, [
131
+ "bold",
132
+ "italic",
133
+ "underline"
134
+ ]);
135
+ const bold = readOptionalBoolean(candidate, "bold", formattingPath);
136
+ const italic = readOptionalBoolean(candidate, "italic", formattingPath);
137
+ const underline = readOptionalBoolean(candidate, "underline", formattingPath);
138
+ if (bold === void 0 && italic === void 0 && underline === void 0) return invalidBatch(formattingPath, "expected at least one formatting property");
139
+ return {
140
+ ...bold !== void 0 && { bold },
141
+ ...italic !== void 0 && { italic },
142
+ ...underline !== void 0 && { underline }
143
+ };
144
+ };
145
+ const readOptionalComment = (value, path) => {
146
+ const candidate = value["comment"];
147
+ if (candidate === void 0) return;
148
+ if (isPlainObject(candidate)) {
149
+ assertAllowedKeys(candidate, `${path}.comment`, ["text"]);
150
+ return { text: readString(candidate, "text", `${path}.comment`) };
151
+ }
152
+ return invalidBatch(`${path}.comment`, "expected an object when provided");
153
+ };
154
+ const readOptionalPrecondition = (value, path) => {
155
+ const candidate = value["precondition"];
156
+ if (candidate === void 0) return;
157
+ if (!isPlainObject(candidate)) return invalidBatch(`${path}.precondition`, "expected an object when provided");
158
+ const preconditionPath = `${path}.precondition`;
159
+ assertAllowedKeys(candidate, preconditionPath, ["blockTextHash"]);
160
+ const blockTextHash = readString(candidate, "blockTextHash", preconditionPath);
161
+ if (!/^h[0-9a-z]+$/.test(blockTextHash)) return invalidBatch(`${preconditionPath}.blockTextHash`, "expected a normalized block text hash");
162
+ return { blockTextHash };
163
+ };
164
+ const isReviewSeverity = (value) => value === "low" || value === "medium" || value === "high";
165
+ const readReviewMeta = (value, path) => {
166
+ const severity = value["severity"];
167
+ if (severity !== void 0 && !isReviewSeverity(severity)) return invalidBatch(`${path}.severity`, "expected \"low\", \"medium\", or \"high\" when provided");
168
+ const area = readOptionalString(value, "area", path);
169
+ return {
170
+ ...severity !== void 0 && { severity },
171
+ ...area !== void 0 && { area }
172
+ };
173
+ };
174
+ const COMMON_OPERATION_KEYS = [
175
+ "id",
176
+ "type",
177
+ "blockId",
178
+ "severity",
179
+ "area",
180
+ "precondition"
181
+ ];
182
+ const parseSignatureParties = (value, path) => {
183
+ const parties = value["parties"];
184
+ if (!Array.isArray(parties)) return invalidBatch(`${path}.parties`, "expected an array");
185
+ return parties.map((party, index) => {
186
+ const partyPath = `${path}.parties[${index}]`;
187
+ if (!isPlainObject(party)) return invalidBatch(partyPath, "expected an object");
188
+ assertAllowedKeys(party, partyPath, [
189
+ "name",
190
+ "signatory",
191
+ "title"
192
+ ]);
193
+ const signatory = readOptionalString(party, "signatory", partyPath);
194
+ const title = readOptionalString(party, "title", partyPath);
195
+ const parsedParty = { name: readString(party, "name", partyPath) };
196
+ if (signatory !== void 0) parsedParty.signatory = signatory;
197
+ if (title !== void 0) parsedParty.title = title;
198
+ return parsedParty;
199
+ });
200
+ };
201
+ const parseDocumentOperation = (value, index) => {
202
+ const path = `$.operations[${index}]`;
203
+ if (!isPlainObject(value)) return invalidBatch(path, "expected an object");
204
+ const id = readString(value, "id", path);
205
+ const type = readString(value, "type", path);
206
+ const reviewMeta = readReviewMeta(value, path);
207
+ const precondition = readOptionalPrecondition(value, path);
208
+ const comment = readOptionalComment(value, path);
209
+ const operationMeta = {
210
+ ...reviewMeta,
211
+ ...precondition !== void 0 && { precondition }
212
+ };
213
+ if (type === "replaceRange") {
214
+ assertAllowedKeys(value, path, [
215
+ "id",
216
+ "type",
217
+ "range",
218
+ "replace",
219
+ "comment",
220
+ "severity",
221
+ "area",
222
+ "precondition"
223
+ ]);
224
+ return {
225
+ ...operationMeta,
226
+ id,
227
+ type,
228
+ range: readTextRange(value, path),
229
+ replace: readString(value, "replace", path),
230
+ ...comment !== void 0 && { comment }
231
+ };
232
+ }
233
+ if (type === "commentOnRange") {
234
+ assertAllowedKeys(value, path, [
235
+ "id",
236
+ "type",
237
+ "range",
238
+ "comment",
239
+ "severity",
240
+ "area",
241
+ "precondition"
242
+ ]);
243
+ if (comment === void 0) return invalidBatch(`${path}.comment`, "expected an object");
244
+ return {
245
+ ...operationMeta,
246
+ id,
247
+ type,
248
+ range: readTextRange(value, path),
249
+ comment
250
+ };
251
+ }
252
+ if (type === "formatRange") {
253
+ assertAllowedKeys(value, path, [
254
+ "id",
255
+ "type",
256
+ "range",
257
+ "formatting",
258
+ "severity",
259
+ "area",
260
+ "precondition"
261
+ ]);
262
+ return {
263
+ ...operationMeta,
264
+ id,
265
+ type,
266
+ range: readTextRange(value, path),
267
+ formatting: readInlineFormatting(value, path)
268
+ };
269
+ }
270
+ const blockId = readString(value, "blockId", path);
271
+ if (type === "replaceInBlock") {
272
+ assertAllowedKeys(value, path, [
273
+ ...COMMON_OPERATION_KEYS,
274
+ "find",
275
+ "replace",
276
+ "comment"
277
+ ]);
278
+ return {
279
+ ...operationMeta,
280
+ id,
281
+ type,
282
+ blockId,
283
+ find: readString(value, "find", path),
284
+ replace: readString(value, "replace", path),
285
+ ...comment !== void 0 && { comment }
286
+ };
287
+ }
288
+ if (type === "insertAfterBlock" || type === "insertBeforeBlock") {
289
+ assertAllowedKeys(value, path, [
290
+ ...COMMON_OPERATION_KEYS,
291
+ "text",
292
+ "inheritFormatting",
293
+ "pageBreakBefore",
294
+ "styleId",
295
+ "comment"
296
+ ]);
297
+ const inheritFormatting = readOptionalBoolean(value, "inheritFormatting", path);
298
+ const pageBreakBefore = readOptionalBoolean(value, "pageBreakBefore", path);
299
+ const styleId = readOptionalString(value, "styleId", path);
300
+ return {
301
+ ...operationMeta,
302
+ id,
303
+ type,
304
+ blockId,
305
+ text: readString(value, "text", path),
306
+ ...inheritFormatting !== void 0 && { inheritFormatting },
307
+ ...pageBreakBefore !== void 0 && { pageBreakBefore },
308
+ ...styleId !== void 0 && { styleId },
309
+ ...comment !== void 0 && { comment }
310
+ };
311
+ }
312
+ if (type === "replaceBlock") {
313
+ assertAllowedKeys(value, path, [
314
+ ...COMMON_OPERATION_KEYS,
315
+ "text",
316
+ "preserveFormatting",
317
+ "styleId",
318
+ "comment"
319
+ ]);
320
+ const preserveFormatting = readOptionalBoolean(value, "preserveFormatting", path);
321
+ const styleId = readOptionalString(value, "styleId", path);
322
+ return {
323
+ ...operationMeta,
324
+ id,
325
+ type,
326
+ blockId,
327
+ text: readString(value, "text", path),
328
+ ...preserveFormatting !== void 0 && { preserveFormatting },
329
+ ...styleId !== void 0 && { styleId },
330
+ ...comment !== void 0 && { comment }
331
+ };
332
+ }
333
+ if (type === "deleteBlock") {
334
+ assertAllowedKeys(value, path, [...COMMON_OPERATION_KEYS, "comment"]);
335
+ return {
336
+ ...operationMeta,
337
+ id,
338
+ type,
339
+ blockId,
340
+ ...comment !== void 0 && { comment }
341
+ };
342
+ }
343
+ if (type === "commentOnBlock") {
344
+ assertAllowedKeys(value, path, [
345
+ ...COMMON_OPERATION_KEYS,
346
+ "quote",
347
+ "comment"
348
+ ]);
349
+ if (comment === void 0) return invalidBatch(`${path}.comment`, "expected an object");
350
+ const quote = readOptionalString(value, "quote", path);
351
+ return {
352
+ ...operationMeta,
353
+ id,
354
+ type,
355
+ blockId,
356
+ ...quote !== void 0 && { quote },
357
+ comment
358
+ };
359
+ }
360
+ if (type === "insertSignatureTable") {
361
+ assertAllowedKeys(value, path, [
362
+ ...COMMON_OPERATION_KEYS,
363
+ "position",
364
+ "parties",
365
+ "comment"
366
+ ]);
367
+ const position = value["position"];
368
+ if (position !== void 0 && position !== "after" && position !== "before") return invalidBatch(`${path}.position`, "expected \"after\" or \"before\" when provided");
369
+ return {
370
+ ...operationMeta,
371
+ id,
372
+ type,
373
+ blockId,
374
+ ...position !== void 0 && { position },
375
+ parties: parseSignatureParties(value, path),
376
+ ...comment !== void 0 && { comment }
377
+ };
378
+ }
379
+ return invalidBatch(`${path}.type`, `unsupported operation type "${type}"`);
380
+ };
381
+ const parseFolioDocumentOperationBatch = (value) => {
382
+ if (!isPlainObject(value)) return invalidBatch("$", "expected an object");
383
+ assertAllowedKeys(value, "$", [
384
+ "version",
385
+ "operations",
386
+ "mode",
387
+ "atomic",
388
+ "dryRun"
389
+ ]);
390
+ const version = assertSupportedFolioDocumentOperationVersion(value["version"]);
391
+ const operations = value["operations"];
392
+ if (!Array.isArray(operations)) return invalidBatch("$.operations", "expected an array");
393
+ const mode = value["mode"];
394
+ if (mode !== void 0 && mode !== "direct" && mode !== "tracked-changes") return invalidBatch("$.mode", "expected \"direct\" or \"tracked-changes\" when provided");
395
+ const atomic = readOptionalBoolean(value, "atomic", "$");
396
+ const dryRun = readOptionalBoolean(value, "dryRun", "$");
397
+ const parsedOperations = operations.map(parseDocumentOperation);
398
+ const operationIds = /* @__PURE__ */ new Set();
399
+ for (const [index, operation] of parsedOperations.entries()) {
400
+ if (operationIds.has(operation.id)) return invalidBatch(`$.operations[${index}].id`, "expected a unique operation id");
401
+ operationIds.add(operation.id);
402
+ }
403
+ return {
404
+ version,
405
+ operations: parsedOperations,
406
+ ...mode !== void 0 && { mode },
407
+ ...atomic !== void 0 && { atomic },
408
+ ...dryRun !== void 0 && { dryRun }
409
+ };
410
+ };
411
+ const recoveryByReason = {
412
+ missingBlock: "refreshDocument",
413
+ changedBlock: "refreshDocument",
414
+ ambiguousFind: "narrowMatch",
415
+ missingFind: "refreshDocument",
416
+ unsupportedBlock: "changeTarget",
417
+ unsupportedMode: "changeMode",
418
+ atomicBatchRejected: "inspectBatch",
419
+ preconditionFailed: "refreshDocument",
420
+ staleRange: "refreshDocument",
421
+ emptyOperation: "removeOperation",
422
+ noopOperation: "removeOperation"
423
+ };
424
+ const getFolioDocumentOperationIssues = (operations, skipped) => {
425
+ const indexById = /* @__PURE__ */ new Map();
426
+ operations.forEach(({ id }, index) => {
427
+ indexById.set(id, index);
428
+ });
429
+ return skipped.map(({ id, reason }) => {
430
+ const operationIndex = indexById.get(id) ?? -1;
431
+ return {
432
+ operationId: id,
433
+ operationIndex,
434
+ path: `$.operations[${operationIndex}]`,
435
+ code: reason,
436
+ retryable: reason !== "emptyOperation" && reason !== "noopOperation",
437
+ recovery: recoveryByReason[reason]
438
+ };
439
+ });
440
+ };
441
+ const getPrimaryAffectedTarget = (operation) => {
442
+ switch (operation.type) {
443
+ case "replaceInBlock":
444
+ case "replaceBlock": return {
445
+ type: "block",
446
+ story: "main",
447
+ blockId: operation.blockId,
448
+ effect: "updated"
449
+ };
450
+ case "replaceRange": return {
451
+ type: "block",
452
+ story: "main",
453
+ blockId: operation.range.blockId,
454
+ effect: "updated"
455
+ };
456
+ case "commentOnRange": return {
457
+ type: "textRange",
458
+ range: operation.range,
459
+ effect: "commented"
460
+ };
461
+ case "formatRange": return {
462
+ type: "textRange",
463
+ range: operation.range,
464
+ effect: "formatted"
465
+ };
466
+ case "insertAfterBlock":
467
+ case "insertBeforeBlock": return {
468
+ type: "insertion",
469
+ story: "main",
470
+ anchorBlockId: operation.blockId,
471
+ position: operation.type === "insertBeforeBlock" ? "before" : "after",
472
+ content: "block"
473
+ };
474
+ case "deleteBlock": return {
475
+ type: "block",
476
+ story: "main",
477
+ blockId: operation.blockId,
478
+ effect: "deleted"
479
+ };
480
+ case "commentOnBlock": return {
481
+ type: "block",
482
+ story: "main",
483
+ blockId: operation.blockId,
484
+ effect: "commented"
485
+ };
486
+ case "insertSignatureTable": return {
487
+ type: "insertion",
488
+ story: "main",
489
+ anchorBlockId: operation.blockId,
490
+ position: operation.position ?? "after",
491
+ content: "signatureTable"
492
+ };
493
+ }
494
+ };
495
+ /** Build deterministic affected-target receipts from operations and their applied entries. */
496
+ const getFolioDocumentOperationReceipts = (operations, applied) => {
497
+ const appliedById = /* @__PURE__ */ new Map();
498
+ applied.forEach((operation) => {
499
+ appliedById.set(operation.id, operation);
500
+ });
501
+ const receipts = [];
502
+ operations.forEach((operation, operationIndex) => {
503
+ const appliedOperation = appliedById.get(operation.id);
504
+ if (!appliedOperation) return;
505
+ const affected = [getPrimaryAffectedTarget(operation)];
506
+ if (appliedOperation.commentId !== void 0) affected.push({
507
+ type: "comment",
508
+ commentId: appliedOperation.commentId
509
+ });
510
+ receipts.push({
511
+ operationId: operation.id,
512
+ operationIndex,
513
+ affected
514
+ });
515
+ });
516
+ return receipts;
517
+ };
518
+ const applyFolioDocumentOperations = ({ view, snapshot, batch, author, createCommentId }) => {
519
+ const parsedBatch = parseFolioDocumentOperationBatch(batch);
520
+ const apply = ({ targetView, targetCreateCommentId = createCommentId, preview = false }) => {
521
+ return (preview ? previewFolioAIEditOperations : applyFolioAIEditOperations)({
522
+ view: targetView,
523
+ snapshot,
524
+ operations: parsedBatch.operations,
525
+ mode: parsedBatch.mode ?? "tracked-changes",
526
+ ...author !== void 0 && { author },
527
+ ...targetCreateCommentId !== void 0 && { createCommentId: targetCreateCommentId }
528
+ });
529
+ };
530
+ const preview = () => apply({
531
+ targetView: view,
532
+ preview: true
533
+ });
534
+ const atomicResult = (previewResult, status) => {
535
+ const skippedById = new Map(previewResult.skipped.map((operation) => [operation.id, operation]));
536
+ const skipped = parsedBatch.operations.map(({ id }) => skippedById.get(id) ?? {
537
+ id,
538
+ reason: "atomicBatchRejected"
539
+ });
540
+ return {
541
+ version: 1,
542
+ status,
543
+ applied: [],
544
+ skipped,
545
+ issues: getFolioDocumentOperationIssues(parsedBatch.operations, skipped),
546
+ receipts: []
547
+ };
548
+ };
549
+ if (parsedBatch.dryRun === true) {
550
+ const previewResult = preview();
551
+ if (parsedBatch.atomic === true && previewResult.skipped.length > 0) return atomicResult(previewResult, "previewed");
552
+ return {
553
+ version: 1,
554
+ status: "previewed",
555
+ applied: previewResult.applied.map(({ id }) => ({ id })),
556
+ skipped: previewResult.skipped,
557
+ issues: getFolioDocumentOperationIssues(parsedBatch.operations, previewResult.skipped),
558
+ receipts: getFolioDocumentOperationReceipts(parsedBatch.operations, previewResult.applied)
559
+ };
560
+ }
561
+ if (parsedBatch.atomic === true) {
562
+ const previewResult = preview();
563
+ if (previewResult.skipped.length > 0) return atomicResult(previewResult, "rejected");
564
+ }
565
+ const result = apply({ targetView: view });
566
+ return {
567
+ version: 1,
568
+ status: "committed",
569
+ ...result,
570
+ issues: getFolioDocumentOperationIssues(parsedBatch.operations, result.skipped),
571
+ receipts: getFolioDocumentOperationReceipts(parsedBatch.operations, result.applied)
572
+ };
573
+ };
574
+ //#endregion
575
+ export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch };
@@ -57,19 +57,30 @@ const computeListMarker = (paragraph, numbering, listCounters, abstractCounters)
57
57
  if (!listRendering || !numbering) return;
58
58
  const { numId, level } = listRendering;
59
59
  if (numId === 0) return;
60
- if (!listCounters.has(numId)) listCounters.set(numId, Array.from({ length: 9 }).fill(0));
60
+ if (!listCounters.has(numId)) listCounters.set(numId, Array.from({ length: 9 }).fill(NaN));
61
61
  const counters = listCounters.get(numId);
62
62
  if (!counters) return;
63
63
  const abstractNumId = numbering.getAbstractNumId(numId);
64
+ const styleNumbering = paragraph.formatting?.numPrFromStyle;
65
+ if (abstractNumId !== null && styleNumbering) {
66
+ const latestAbstractCounters = abstractCounters.get(abstractNumId);
67
+ if (latestAbstractCounters) for (let i = 0; i < counters.length; i += 1) counters[i] = latestAbstractCounters[i] ?? NaN;
68
+ }
64
69
  if (abstractNumId !== null && level > 0) {
65
70
  const latestAbstractCounters = abstractCounters.get(abstractNumId);
66
- const missingParentCounters = counters.slice(0, level).every((value) => value === 0);
67
- if (latestAbstractCounters && missingParentCounters) for (let i = 0; i < level; i += 1) counters[i] = latestAbstractCounters[i] ?? 0;
71
+ if (counters.slice(0, level).every(Number.isNaN)) for (let i = 0; i < level; i += 1) {
72
+ const latestCounter = latestAbstractCounters?.[i];
73
+ counters[i] = latestCounter !== void 0 && !Number.isNaN(latestCounter) ? latestCounter : numbering.getLevel(numId, i)?.start ?? 1;
74
+ }
68
75
  }
69
- counters[level] = (counters[level] || 0) + 1;
70
- for (let i = level + 1; i < counters.length; i += 1) counters[i] = 0;
76
+ if (Number.isNaN(counters[level])) counters[level] = (numbering.getLevel(numId, level)?.start ?? 1) - 1;
77
+ counters[level] = (counters[level] ?? 0) + 1;
78
+ for (let i = level + 1; i < counters.length; i += 1) counters[i] = NaN;
71
79
  const childAdvances = listRendering.implicitChildLevelAdvances ?? 0;
72
- if (childAdvances > 0 && level + 1 < counters.length) counters[level + 1] = (counters[level + 1] ?? 0) + childAdvances;
80
+ if (childAdvances > 0 && level + 1 < counters.length) {
81
+ const childCounter = counters[level + 1];
82
+ counters[level + 1] = (childCounter === void 0 || Number.isNaN(childCounter) ? 0 : childCounter) + childAdvances;
83
+ }
73
84
  if (abstractNumId !== null) abstractCounters.set(abstractNumId, [...counters]);
74
85
  const pattern = listRendering.marker;
75
86
  if (listRendering.isBullet) {
@@ -90,7 +101,6 @@ const computeListMarker = (paragraph, numbering, listCounters, abstractCounters)
90
101
  listRendering.marker = computedMarker;
91
102
  };
92
103
  const enrichParagraphTextBoxes = (paragraph, paraXml, styles, theme, numbering, rels, media) => {
93
- if (paragraph.content.length === 0) return;
94
104
  const xmlChildren = getChildElements(paraXml);
95
105
  let parsedIndex = 0;
96
106
  let lastConsumedRun;
@@ -0,0 +1,6 @@
1
+ import { AgileKeyMaterial } from "./encryptionInfo.js";
2
+
3
+ //#region src/docx/encryption/agileDecryption.d.ts
4
+ declare const decryptAgileEncryptedPackage: (password: string, material: AgileKeyMaterial, encryptedPackage: Uint8Array) => Promise<Uint8Array>;
5
+ //#endregion
6
+ export { decryptAgileEncryptedPackage };