ooxml-core 0.12.0 → 0.14.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 (37) hide show
  1. package/dist/collab/broadcast-transport.d.ts +21 -0
  2. package/dist/collab/broadcast-transport.d.ts.map +1 -0
  3. package/dist/collab/index.cjs +103 -0
  4. package/dist/collab/index.d.ts +2 -0
  5. package/dist/collab/index.d.ts.map +1 -1
  6. package/dist/collab/index.mjs +100 -1
  7. package/dist/collab/package-adapter.d.ts +15 -0
  8. package/dist/collab/package-adapter.d.ts.map +1 -0
  9. package/dist/crypto/index.cjs +118 -31
  10. package/dist/crypto/index.mjs +118 -31
  11. package/dist/docx/load/index.cjs +1273 -110
  12. package/dist/docx/load/index.mjs +1273 -110
  13. package/dist/docx/load/legacy-doc.d.ts.map +1 -1
  14. package/dist/pptx/automation/index.cjs +1479 -304
  15. package/dist/pptx/automation/index.d.ts +1 -1
  16. package/dist/pptx/automation/index.mjs +1479 -304
  17. package/dist/pptx/chunks/{index-LoCVDu8Z.d.ts → index-CT9y69AZ.d.ts} +22 -12
  18. package/dist/pptx/chunks/index-CT9y69AZ.d.ts.map +1 -0
  19. package/dist/pptx/cli/index.cjs +307 -152
  20. package/dist/pptx/cli/index.mjs +307 -152
  21. package/dist/pptx/index.cjs +1479 -304
  22. package/dist/pptx/index.d.ts +1 -1
  23. package/dist/pptx/index.mjs +1479 -304
  24. package/dist/visio/index.cjs +7498 -127
  25. package/dist/visio/index.d.ts +3 -1
  26. package/dist/visio/index.d.ts.map +1 -1
  27. package/dist/visio/index.mjs +7497 -128
  28. package/dist/visio/legacy.d.ts +10 -0
  29. package/dist/visio/legacy.d.ts.map +1 -0
  30. package/dist/visio/load.d.ts +5 -0
  31. package/dist/visio/load.d.ts.map +1 -0
  32. package/dist/visio/model.d.ts +1 -1
  33. package/dist/visio/model.d.ts.map +1 -1
  34. package/dist/xlsx/load/index.cjs +144 -52
  35. package/dist/xlsx/load/index.mjs +144 -52
  36. package/package.json +2 -2
  37. package/dist/pptx/chunks/index-LoCVDu8Z.d.ts.map +0 -1
@@ -0,0 +1,21 @@
1
+ import type { Transport } from './provider.js';
2
+ /** Structural BroadcastChannel, so the area needs no DOM types. */
3
+ export interface BroadcastChannelLike {
4
+ postMessage: (message: unknown) => void;
5
+ close: () => void;
6
+ onmessage: ((event: {
7
+ data: unknown;
8
+ }) => void) | null;
9
+ }
10
+ export type BroadcastChannelConstructor = new (name: string) => BroadcastChannelLike;
11
+ export interface BroadcastTransportOptions {
12
+ roomId: string;
13
+ /** Channel name prefix; one channel per room. Default `ooxml-collab:`. */
14
+ prefix?: string;
15
+ /** Defaults to `globalThis.BroadcastChannel`. */
16
+ BroadcastChannel?: BroadcastChannelConstructor;
17
+ }
18
+ /** Whether this environment can create a BroadcastChannel transport. */
19
+ export declare function canBroadcast(scope?: object): boolean;
20
+ export declare function createBroadcastTransport(options: BroadcastTransportOptions): Transport;
21
+ //# sourceMappingURL=broadcast-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast-transport.d.ts","sourceRoot":"","sources":["../../src/collab/broadcast-transport.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,eAAe,CAAC;AAGlE,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACpC,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CACvD;AACD,MAAM,MAAM,2BAA2B,GAAG,KAAK,IAAI,EAAE,MAAM,KAAK,oBAAoB,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,2BAA2B,CAAC;CAC/C;AAaD,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,KAAK,GAAE,MAAmB,GAAG,OAAO,CAEhE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,SAAS,CAmDtF"}
@@ -485,6 +485,62 @@ function bindDocument(session, adapter, options) {
485
485
  }
486
486
  };
487
487
  }
488
+
489
+ // src/collab/broadcast-transport.ts
490
+ var isEnvelope = (value) => {
491
+ const envelope = value;
492
+ return !!envelope && typeof envelope.from === "string" && (envelope.kind === "hello" || envelope.kind === "data" && envelope.data instanceof Uint8Array);
493
+ };
494
+ function canBroadcast(scope = globalThis) {
495
+ return typeof scope.BroadcastChannel === "function";
496
+ }
497
+ function createBroadcastTransport(options) {
498
+ const roomId = validateRoomId(options.roomId);
499
+ const Channel = options.BroadcastChannel ?? globalThis.BroadcastChannel;
500
+ const self = Math.random().toString(36).slice(2) + Date.now().toString(36);
501
+ let channel = null;
502
+ let handlers = null;
503
+ const close = () => {
504
+ if (!channel) return;
505
+ channel.onmessage = null;
506
+ channel.close();
507
+ channel = null;
508
+ };
509
+ return {
510
+ connect(next) {
511
+ close();
512
+ handlers = next;
513
+ if (!Channel) {
514
+ next.error(new Error("BroadcastChannel is not available in this environment."));
515
+ next.close("unavailable");
516
+ return;
517
+ }
518
+ const open = new Channel(`${options.prefix ?? "ooxml-collab:"}${roomId}`);
519
+ channel = open;
520
+ open.onmessage = ({ data }) => {
521
+ if (channel !== open || !isEnvelope(data) || data.from === self) return;
522
+ if (data.kind === "hello") handlers?.peer?.();
523
+ else handlers?.message(data.data);
524
+ };
525
+ next.open();
526
+ open.postMessage({ kind: "hello", from: self });
527
+ },
528
+ send(data) {
529
+ try {
530
+ channel?.postMessage({ kind: "data", from: self, data });
531
+ } catch (cause) {
532
+ handlers?.error(cause instanceof Error ? cause : new Error(String(cause)));
533
+ }
534
+ },
535
+ disconnect() {
536
+ const was = handlers;
537
+ const open = channel !== null;
538
+ close();
539
+ handlers = null;
540
+ if (open) was?.close("disconnected");
541
+ }
542
+ };
543
+ }
488
544
  var MAX_UPDATE_BYTES = 32 * 1024 * 1024;
489
545
  function encodeSnapshot(doc) {
490
546
  return Y__namespace.encodeStateAsUpdate(doc);
@@ -801,6 +857,49 @@ function createMemoryHub(options = {}) {
801
857
  };
802
858
  }
803
859
 
860
+ // src/collab/package-adapter.ts
861
+ var DEFAULT_MAX_PACKAGE_BYTES = 32 * 1024 * 1024;
862
+ function packageAdapter(options = {}) {
863
+ const name = options.name ?? "package";
864
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_PACKAGE_BYTES;
865
+ const map = (doc) => doc.getMap(name);
866
+ const check = (bytes) => {
867
+ if (!(bytes instanceof Uint8Array)) throw new Error("The shared package is not binary data.");
868
+ if (bytes.byteLength > maxBytes)
869
+ throw new Error(`The shared package exceeds ${Math.round(maxBytes / 1024 / 1024)} MiB.`);
870
+ return bytes;
871
+ };
872
+ return {
873
+ isEmpty: (doc) => !(map(doc).get("bytes") instanceof Uint8Array),
874
+ read: (doc) => {
875
+ const shared = map(doc);
876
+ const revision = shared.get("revision");
877
+ return {
878
+ bytes: check(shared.get("bytes")).slice(),
879
+ revision: typeof revision === "number" && Number.isSafeInteger(revision) ? revision : 0
880
+ };
881
+ },
882
+ write: (doc, model, origin) => {
883
+ const bytes = check(model.bytes);
884
+ doc.transact(() => {
885
+ const shared = map(doc);
886
+ const current = shared.get("revision");
887
+ const revision = Math.max(model.revision, typeof current === "number" ? current : 0) + 1;
888
+ shared.set("bytes", bytes.slice());
889
+ shared.set("revision", revision);
890
+ }, origin);
891
+ },
892
+ observe: (doc, onChange) => {
893
+ const shared = map(doc);
894
+ const handler = (event) => {
895
+ if (event.keysChanged.has("bytes")) onChange(event.transaction.origin);
896
+ };
897
+ shared.observe(handler);
898
+ return () => shared.unobserve(handler);
899
+ }
900
+ };
901
+ }
902
+
804
903
  // src/collab/ordering.ts
805
904
  function classifyVersion(messageVersion, currentVersion) {
806
905
  if (!isNonNegativeSafeInteger(messageVersion) || !isNonNegativeSafeInteger(currentVersion))
@@ -1253,6 +1352,7 @@ exports.COLLAB_LEAVE_MESSAGE = COLLAB_LEAVE_MESSAGE;
1253
1352
  exports.CONNECTION_TIMEOUT_MS = CONNECTION_TIMEOUT_MS;
1254
1353
  exports.CURSOR_PALETTE = CURSOR_PALETTE;
1255
1354
  exports.DEFAULT_COLOR = DEFAULT_COLOR;
1355
+ exports.DEFAULT_MAX_PACKAGE_BYTES = DEFAULT_MAX_PACKAGE_BYTES;
1256
1356
  exports.DEPARTURE_CHANNEL = DEPARTURE_CHANNEL;
1257
1357
  exports.Emitter = Emitter;
1258
1358
  exports.INITIAL_SYNC_GRACE_MS = INITIAL_SYNC_GRACE_MS;
@@ -1276,11 +1376,13 @@ exports.assignUserColor = assignUserColor;
1276
1376
  exports.bindDocument = bindDocument;
1277
1377
  exports.borrowAwareness = borrowAwareness;
1278
1378
  exports.buildRoster = buildRoster;
1379
+ exports.canBroadcast = canBroadcast;
1279
1380
  exports.canWrite = canWrite;
1280
1381
  exports.clampCoordinate = clampCoordinate;
1281
1382
  exports.classifyVersion = classifyVersion;
1282
1383
  exports.clearLocalAwareness = clearLocalAwareness;
1283
1384
  exports.createAssetSync = createAssetSync;
1385
+ exports.createBroadcastTransport = createBroadcastTransport;
1284
1386
  exports.createClientId = createClientId;
1285
1387
  exports.createCollabSession = createCollabSession;
1286
1388
  exports.createDepartureChannel = createDepartureChannel;
@@ -1306,6 +1408,7 @@ exports.isValidId = isValidId;
1306
1408
  exports.isValidRoomId = isValidRoomId;
1307
1409
  exports.mergeUpdates = mergeUpdates2;
1308
1410
  exports.observeExternalSession = observeExternalSession;
1411
+ exports.packageAdapter = packageAdapter;
1309
1412
  exports.presenceToCursors = presenceToCursors;
1310
1413
  exports.registerTeardown = registerTeardown;
1311
1414
  exports.removeAwarenessStatesLocally = removeAwarenessStatesLocally;
@@ -1,12 +1,14 @@
1
1
  export * from './assets.js';
2
2
  export * from './awareness.js';
3
3
  export * from './binding.js';
4
+ export * from './broadcast-transport.js';
4
5
  export * from './codec.js';
5
6
  export * from './emitter.js';
6
7
  export * from './external-provider.js';
7
8
  export * from './identity.js';
8
9
  export * from './lifecycle.js';
9
10
  export * from './memory-transport.js';
11
+ export * from './package-adapter.js';
10
12
  export * from './ordering.js';
11
13
  export * from './policy.js';
12
14
  export * from './presence.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAIA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/collab/index.ts"],"names":[],"mappings":"AAIA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC"}
@@ -461,6 +461,62 @@ function bindDocument(session, adapter, options) {
461
461
  }
462
462
  };
463
463
  }
464
+
465
+ // src/collab/broadcast-transport.ts
466
+ var isEnvelope = (value) => {
467
+ const envelope = value;
468
+ return !!envelope && typeof envelope.from === "string" && (envelope.kind === "hello" || envelope.kind === "data" && envelope.data instanceof Uint8Array);
469
+ };
470
+ function canBroadcast(scope = globalThis) {
471
+ return typeof scope.BroadcastChannel === "function";
472
+ }
473
+ function createBroadcastTransport(options) {
474
+ const roomId = validateRoomId(options.roomId);
475
+ const Channel = options.BroadcastChannel ?? globalThis.BroadcastChannel;
476
+ const self = Math.random().toString(36).slice(2) + Date.now().toString(36);
477
+ let channel = null;
478
+ let handlers = null;
479
+ const close = () => {
480
+ if (!channel) return;
481
+ channel.onmessage = null;
482
+ channel.close();
483
+ channel = null;
484
+ };
485
+ return {
486
+ connect(next) {
487
+ close();
488
+ handlers = next;
489
+ if (!Channel) {
490
+ next.error(new Error("BroadcastChannel is not available in this environment."));
491
+ next.close("unavailable");
492
+ return;
493
+ }
494
+ const open = new Channel(`${options.prefix ?? "ooxml-collab:"}${roomId}`);
495
+ channel = open;
496
+ open.onmessage = ({ data }) => {
497
+ if (channel !== open || !isEnvelope(data) || data.from === self) return;
498
+ if (data.kind === "hello") handlers?.peer?.();
499
+ else handlers?.message(data.data);
500
+ };
501
+ next.open();
502
+ open.postMessage({ kind: "hello", from: self });
503
+ },
504
+ send(data) {
505
+ try {
506
+ channel?.postMessage({ kind: "data", from: self, data });
507
+ } catch (cause) {
508
+ handlers?.error(cause instanceof Error ? cause : new Error(String(cause)));
509
+ }
510
+ },
511
+ disconnect() {
512
+ const was = handlers;
513
+ const open = channel !== null;
514
+ close();
515
+ handlers = null;
516
+ if (open) was?.close("disconnected");
517
+ }
518
+ };
519
+ }
464
520
  var MAX_UPDATE_BYTES = 32 * 1024 * 1024;
465
521
  function encodeSnapshot(doc) {
466
522
  return Y.encodeStateAsUpdate(doc);
@@ -777,6 +833,49 @@ function createMemoryHub(options = {}) {
777
833
  };
778
834
  }
779
835
 
836
+ // src/collab/package-adapter.ts
837
+ var DEFAULT_MAX_PACKAGE_BYTES = 32 * 1024 * 1024;
838
+ function packageAdapter(options = {}) {
839
+ const name = options.name ?? "package";
840
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_PACKAGE_BYTES;
841
+ const map = (doc) => doc.getMap(name);
842
+ const check = (bytes) => {
843
+ if (!(bytes instanceof Uint8Array)) throw new Error("The shared package is not binary data.");
844
+ if (bytes.byteLength > maxBytes)
845
+ throw new Error(`The shared package exceeds ${Math.round(maxBytes / 1024 / 1024)} MiB.`);
846
+ return bytes;
847
+ };
848
+ return {
849
+ isEmpty: (doc) => !(map(doc).get("bytes") instanceof Uint8Array),
850
+ read: (doc) => {
851
+ const shared = map(doc);
852
+ const revision = shared.get("revision");
853
+ return {
854
+ bytes: check(shared.get("bytes")).slice(),
855
+ revision: typeof revision === "number" && Number.isSafeInteger(revision) ? revision : 0
856
+ };
857
+ },
858
+ write: (doc, model, origin) => {
859
+ const bytes = check(model.bytes);
860
+ doc.transact(() => {
861
+ const shared = map(doc);
862
+ const current = shared.get("revision");
863
+ const revision = Math.max(model.revision, typeof current === "number" ? current : 0) + 1;
864
+ shared.set("bytes", bytes.slice());
865
+ shared.set("revision", revision);
866
+ }, origin);
867
+ },
868
+ observe: (doc, onChange) => {
869
+ const shared = map(doc);
870
+ const handler = (event) => {
871
+ if (event.keysChanged.has("bytes")) onChange(event.transaction.origin);
872
+ };
873
+ shared.observe(handler);
874
+ return () => shared.unobserve(handler);
875
+ }
876
+ };
877
+ }
878
+
780
879
  // src/collab/ordering.ts
781
880
  function classifyVersion(messageVersion, currentVersion) {
782
881
  if (!isNonNegativeSafeInteger(messageVersion) || !isNonNegativeSafeInteger(currentVersion))
@@ -1222,4 +1321,4 @@ function createWebSocketTransport(options) {
1222
1321
  };
1223
1322
  }
1224
1323
 
1225
- export { BROADCAST_THROTTLE_MS, BoundedMap, COLLABORATION_ROLES, COLLAB_LEAVE_MESSAGE, CONNECTION_TIMEOUT_MS, CURSOR_PALETTE, DEFAULT_COLOR, DEPARTURE_CHANNEL, Emitter, INITIAL_SYNC_GRACE_MS, IdempotencyCache, LEGACY_PPTX_DEPARTURE_CHANNEL, LEGACY_PPTX_LEAVE_MESSAGE, LOCAL_ORIGIN, MAX_LABEL_CHARS, MAX_UPDATE_BYTES, MESSAGE_AWARENESS, MESSAGE_QUERY_AWARENESS, MESSAGE_SYNC, PRESENCE_FIELD, PRESENCE_HEARTBEAT_MS, STALE_PRESENCE_MS, SequenceTracker, adaptYjsProvider, applyUpdateSafe, asSelectionIds, assignUserColor, bindDocument, borrowAwareness, buildRoster, canWrite, clampCoordinate, classifyVersion, clearLocalAwareness, createAssetSync, createClientId, createCollabSession, createDepartureChannel, createIdGenerator, createMemoryHub, createPresencePublisher, createSyncGate, createTransportProvider, createWebSocketTransport, deriveCanvasPresence, derivePresence, encodeDiff, encodeSnapshot, encodeStateVector2 as encodeStateVector, formatCursorLabel, freezeDeep, fromBase64, getUserInitials, isMixedContentBlocked, isNonNegativeSafeInteger, isPresenceFresh, isValidId, isValidRoomId, mergeUpdates2 as mergeUpdates, observeExternalSession, presenceToCursors, registerTeardown, removeAwarenessStatesLocally, restoreSnapshot, roomUrl, sanitizeAvatarUrl, sanitizeCanvasPayload, sanitizeColor, sanitizeIdentity, sanitizeIndex, sanitizeRole, sanitizeUserName, shouldAutoFollowBroadcaster, shouldRoomReplaceLoad, stripHtmlTags, toBase64, transportProvider, validateDisplayName, validateRoomId, validateUpdate };
1324
+ export { BROADCAST_THROTTLE_MS, BoundedMap, COLLABORATION_ROLES, COLLAB_LEAVE_MESSAGE, CONNECTION_TIMEOUT_MS, CURSOR_PALETTE, DEFAULT_COLOR, DEFAULT_MAX_PACKAGE_BYTES, DEPARTURE_CHANNEL, Emitter, INITIAL_SYNC_GRACE_MS, IdempotencyCache, LEGACY_PPTX_DEPARTURE_CHANNEL, LEGACY_PPTX_LEAVE_MESSAGE, LOCAL_ORIGIN, MAX_LABEL_CHARS, MAX_UPDATE_BYTES, MESSAGE_AWARENESS, MESSAGE_QUERY_AWARENESS, MESSAGE_SYNC, PRESENCE_FIELD, PRESENCE_HEARTBEAT_MS, STALE_PRESENCE_MS, SequenceTracker, adaptYjsProvider, applyUpdateSafe, asSelectionIds, assignUserColor, bindDocument, borrowAwareness, buildRoster, canBroadcast, canWrite, clampCoordinate, classifyVersion, clearLocalAwareness, createAssetSync, createBroadcastTransport, createClientId, createCollabSession, createDepartureChannel, createIdGenerator, createMemoryHub, createPresencePublisher, createSyncGate, createTransportProvider, createWebSocketTransport, deriveCanvasPresence, derivePresence, encodeDiff, encodeSnapshot, encodeStateVector2 as encodeStateVector, formatCursorLabel, freezeDeep, fromBase64, getUserInitials, isMixedContentBlocked, isNonNegativeSafeInteger, isPresenceFresh, isValidId, isValidRoomId, mergeUpdates2 as mergeUpdates, observeExternalSession, packageAdapter, presenceToCursors, registerTeardown, removeAwarenessStatesLocally, restoreSnapshot, roomUrl, sanitizeAvatarUrl, sanitizeCanvasPayload, sanitizeColor, sanitizeIdentity, sanitizeIndex, sanitizeRole, sanitizeUserName, shouldAutoFollowBroadcaster, shouldRoomReplaceLoad, stripHtmlTags, toBase64, transportProvider, validateDisplayName, validateRoomId, validateUpdate };
@@ -0,0 +1,15 @@
1
+ import type { DocumentAdapter } from './binding.js';
2
+ export interface PackageAdapterOptions {
3
+ /** Y.Map name. Default `package`. */
4
+ name?: string;
5
+ /** Refuse to publish or adopt packages larger than this. Default 32 MiB. */
6
+ maxBytes?: number;
7
+ }
8
+ export declare const DEFAULT_MAX_PACKAGE_BYTES: number;
9
+ /** One shared package: its bytes and a revision counter peers can display or compare. */
10
+ export interface SharedPackage {
11
+ bytes: Uint8Array;
12
+ revision: number;
13
+ }
14
+ export declare function packageAdapter(options?: PackageAdapterOptions): DocumentAdapter<SharedPackage>;
15
+ //# sourceMappingURL=package-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-adapter.d.ts","sourceRoot":"","sources":["../../src/collab/package-adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACrC,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAC7B,OAAO,GAAE,qBAA0B,GACjC,eAAe,CAAC,aAAa,CAAC,CAwChC"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
3
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-types.js
4
4
  var OLE_MAGIC = new Uint8Array([208, 207, 17, 224, 161, 177, 26, 225]);
5
5
  var ENDOFCHAIN = 4294967294;
6
6
  var FREESECT = 4294967295;
@@ -18,10 +18,13 @@ var Ole2ParseError = class extends Error {
18
18
  }
19
19
  };
20
20
 
21
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
21
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-read.js
22
22
  function parseOle2(buffer) {
23
23
  const data = new Uint8Array(buffer);
24
24
  const view = new DataView(buffer);
25
+ if (data.length < 512) {
26
+ throw new Ole2ParseError("Truncated OLE2 compound file header");
27
+ }
25
28
  for (let i = 0; i < OLE_MAGIC.length; i++) {
26
29
  if (data[i] !== OLE_MAGIC[i]) {
27
30
  throw new Ole2ParseError("Not a valid OLE2 compound file");
@@ -35,8 +38,15 @@ function parseOle2(buffer) {
35
38
  }
36
39
  const sectorSizePower = view.getUint16(30, true);
37
40
  const miniSectorSizePower = view.getUint16(32, true);
41
+ if (majorVersion !== 3 && majorVersion !== 4 || sectorSizePower !== (majorVersion === 3 ? 9 : 12) || miniSectorSizePower !== 6) {
42
+ throw new Ole2ParseError("Unsupported OLE2 version or sector size");
43
+ }
38
44
  const sectorSize = 1 << sectorSizePower;
39
45
  const miniSectorSize = 1 << miniSectorSizePower;
46
+ if (data.length < sectorSize || data.length % sectorSize !== 0) {
47
+ throw new Ole2ParseError("Truncated OLE2 sector");
48
+ }
49
+ const sectorCount = data.length / sectorSize - 1;
40
50
  const totalFATSectors = view.getUint32(44, true);
41
51
  const firstDirectorySector = view.getUint32(48, true);
42
52
  const miniStreamCutoff = view.getUint32(56, true);
@@ -44,6 +54,9 @@ function parseOle2(buffer) {
44
54
  const totalMiniFATSectors = view.getUint32(64, true);
45
55
  const firstDIFATSector = view.getUint32(68, true);
46
56
  const totalDIFATSectors = view.getUint32(72, true);
57
+ if (totalFATSectors > sectorCount || totalMiniFATSectors > sectorCount || totalDIFATSectors > sectorCount) {
58
+ throw new Ole2ParseError("Allocation table count exceeds file size");
59
+ }
47
60
  function sectorOffset(sector) {
48
61
  return (sector + 1) * sectorSize;
49
62
  }
@@ -62,7 +75,11 @@ function parseOle2(buffer) {
62
75
  }
63
76
  }
64
77
  let difatSector = firstDIFATSector;
78
+ const difatSeen = /* @__PURE__ */ new Set();
65
79
  for (let d = 0; d < totalDIFATSectors && difatSector <= MAXREGSECT; d++) {
80
+ if (difatSeen.has(difatSector))
81
+ throw new Ole2ParseError("Circular DIFAT chain");
82
+ difatSeen.add(difatSector);
66
83
  const difatData = readSector(difatSector);
67
84
  const difatView = new DataView(difatData.buffer, difatData.byteOffset, difatData.byteLength);
68
85
  const entriesPerSector = (sectorSize - 4) / 4;
@@ -74,11 +91,14 @@ function parseOle2(buffer) {
74
91
  }
75
92
  difatSector = difatView.getUint32(sectorSize - 4, true);
76
93
  }
94
+ if (difatSeen.size !== totalDIFATSectors || fatSectors.length !== totalFATSectors || new Set(fatSectors).size !== fatSectors.length || fatSectors.some((id) => difatSeen.has(id))) {
95
+ throw new Ole2ParseError("Invalid DIFAT allocation table");
96
+ }
77
97
  const fatEntries = [];
78
98
  for (const fatSector of fatSectors) {
79
99
  const fatData = readSector(fatSector);
80
100
  const fatView = new DataView(fatData.buffer, fatData.byteOffset, fatData.byteLength);
81
- for (let i = 0; i < sectorSize / 4; i++) {
101
+ for (let i = 0; i < sectorSize / 4 && fatEntries.length < sectorCount; i++) {
82
102
  fatEntries.push(fatView.getUint32(i * 4, true));
83
103
  }
84
104
  }
@@ -92,8 +112,12 @@ function parseOle2(buffer) {
92
112
  }
93
113
  visited.add(current);
94
114
  sectors.push(readSector(current));
95
- current = fatEntries[current] ?? ENDOFCHAIN;
115
+ if (fatEntries[current] === void 0)
116
+ throw new Ole2ParseError("Missing FAT chain entry");
117
+ current = fatEntries[current];
96
118
  }
119
+ if (current !== ENDOFCHAIN)
120
+ throw new Ole2ParseError("Invalid FAT chain terminator");
97
121
  const totalLength = sectors.length * sectorSize;
98
122
  const result = new Uint8Array(totalLength);
99
123
  let offset = 0;
@@ -104,16 +128,14 @@ function parseOle2(buffer) {
104
128
  return result;
105
129
  }
106
130
  function readStream(startSector, size) {
131
+ if (size === 0)
132
+ return new Uint8Array(0);
133
+ if (size > sectorCount * sectorSize)
134
+ throw new Ole2ParseError("Stream size exceeds file size");
107
135
  const raw = readSectorChain(startSector);
108
- return raw.subarray(0, Math.min(size, raw.length));
109
- }
110
- const miniFatEntries = [];
111
- if (firstMiniFATSector <= MAXREGSECT && totalMiniFATSectors > 0) {
112
- const miniFatRaw = readSectorChain(firstMiniFATSector);
113
- const miniFatView = new DataView(miniFatRaw.buffer, miniFatRaw.byteOffset, miniFatRaw.byteLength);
114
- for (let i = 0; i < miniFatRaw.length / 4; i++) {
115
- miniFatEntries.push(miniFatView.getUint32(i * 4, true));
116
- }
136
+ if (raw.length < size)
137
+ throw new Ole2ParseError("Truncated stream sector chain");
138
+ return raw.subarray(0, size);
117
139
  }
118
140
  const dirRaw = readSectorChain(firstDirectorySector);
119
141
  const numEntries = Math.floor(dirRaw.length / DIR_ENTRY_SIZE);
@@ -126,6 +148,9 @@ function parseOle2(buffer) {
126
148
  if (objectType === ENTRY_TYPE_EMPTY) {
127
149
  continue;
128
150
  }
151
+ if (nameLen < 2 || nameLen > 64 || nameLen % 2 !== 0 || entryView.getUint16(nameLen - 2, true) !== 0) {
152
+ throw new Ole2ParseError("Invalid directory entry name");
153
+ }
129
154
  const nameBytes = Math.max(0, nameLen - 2);
130
155
  let name = "";
131
156
  for (let j = 0; j < nameBytes; j += 2) {
@@ -139,8 +164,11 @@ function parseOle2(buffer) {
139
164
  const sizeLow = entryView.getUint32(120, true);
140
165
  let size = sizeLow;
141
166
  if (majorVersion === 4) {
142
- entryView.getUint32(124, true);
143
- size = sizeLow;
167
+ const sizeHigh = entryView.getUint32(124, true);
168
+ size = sizeLow + sizeHigh * 4294967296;
169
+ if (!Number.isSafeInteger(size) || size > sectorCount * sectorSize) {
170
+ throw new Ole2ParseError("Stream size exceeds supported file bounds");
171
+ }
144
172
  }
145
173
  entries.push({
146
174
  name,
@@ -154,11 +182,28 @@ function parseOle2(buffer) {
154
182
  });
155
183
  }
156
184
  const rootEntry = entries.find((e) => e.type === ENTRY_TYPE_ROOT);
185
+ if (!rootEntry || entries.filter((e) => e.type === ENTRY_TYPE_ROOT).length !== 1) {
186
+ throw new Ole2ParseError("Invalid root directory entry");
187
+ }
157
188
  let miniStreamData;
158
189
  if (rootEntry && rootEntry.startSector <= MAXREGSECT) {
159
- miniStreamData = readSectorChain(rootEntry.startSector);
190
+ miniStreamData = readStream(rootEntry.startSector, rootEntry.size);
191
+ }
192
+ const miniFatEntries = [];
193
+ if (firstMiniFATSector <= MAXREGSECT && totalMiniFATSectors > 0) {
194
+ const miniFatRaw = readSectorChain(firstMiniFATSector);
195
+ if (miniFatRaw.length !== totalMiniFATSectors * sectorSize) {
196
+ throw new Ole2ParseError("Unexpected mini FAT chain length");
197
+ }
198
+ const miniFatView = new DataView(miniFatRaw.buffer, miniFatRaw.byteOffset, miniFatRaw.byteLength);
199
+ const miniCapacity = Math.floor((miniStreamData?.length ?? 0) / miniSectorSize);
200
+ for (let i = 0; i < miniFatRaw.length / 4 && i < miniCapacity; i++) {
201
+ miniFatEntries.push(miniFatView.getUint32(i * 4, true));
202
+ }
160
203
  }
161
204
  function readMiniStream(startSector, size) {
205
+ if (size === 0)
206
+ return new Uint8Array(0);
162
207
  if (!miniStreamData) {
163
208
  throw new Ole2ParseError("Mini stream container not found");
164
209
  }
@@ -171,17 +216,24 @@ function parseOle2(buffer) {
171
216
  }
172
217
  visited.add(current);
173
218
  const offset2 = current * miniSectorSize;
219
+ if (offset2 + miniSectorSize > miniStreamData.length || miniFatEntries[current] === void 0) {
220
+ throw new Ole2ParseError("Mini stream sector exceeds allocation bounds");
221
+ }
174
222
  sectors.push(miniStreamData.subarray(offset2, offset2 + miniSectorSize));
175
- current = miniFatEntries[current] ?? ENDOFCHAIN;
223
+ current = miniFatEntries[current];
176
224
  }
225
+ if (current !== ENDOFCHAIN)
226
+ throw new Ole2ParseError("Invalid mini FAT chain terminator");
177
227
  const totalLength = sectors.length * miniSectorSize;
228
+ if (totalLength < size)
229
+ throw new Ole2ParseError("Truncated mini stream sector chain");
178
230
  const result = new Uint8Array(totalLength);
179
231
  let offset = 0;
180
232
  for (const sector of sectors) {
181
233
  result.set(sector, offset);
182
234
  offset += miniSectorSize;
183
235
  }
184
- return result.subarray(0, Math.min(size, result.length));
236
+ return result.subarray(0, size);
185
237
  }
186
238
  function getStream(name) {
187
239
  const entry = entries.find((e) => (e.type === ENTRY_TYPE_STREAM || e.type === ENTRY_TYPE_ROOT) && e.name === name);
@@ -196,7 +248,7 @@ function parseOle2(buffer) {
196
248
  return { entries, getStream };
197
249
  }
198
250
 
199
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js
251
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/utils/ooxml-crypto-primitives.js
200
252
  function getSubtle() {
201
253
  if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.subtle) {
202
254
  return globalThis.crypto.subtle;
@@ -1128,13 +1180,16 @@ var EncryptedFileError = class extends Error {
1128
1180
  }
1129
1181
  };
1130
1182
 
1131
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
1183
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-helpers.js
1132
1184
  function compareDirEntryNames(a, b) {
1185
+ const ua = a.toUpperCase();
1186
+ const ub = b.toUpperCase();
1187
+ if (ua.length !== a.length || ub.length !== b.length) {
1188
+ throw new Error("CFB stream names with expanding uppercase mappings are unsupported");
1189
+ }
1133
1190
  if (a.length !== b.length) {
1134
1191
  return a.length - b.length;
1135
1192
  }
1136
- const ua = a.toUpperCase();
1137
- const ub = b.toUpperCase();
1138
1193
  for (let i = 0; i < ua.length; i++) {
1139
1194
  const diff = ua.charCodeAt(i) - ub.charCodeAt(i);
1140
1195
  if (diff !== 0) {
@@ -1151,6 +1206,24 @@ function encodeName(name) {
1151
1206
  }
1152
1207
  return bytes;
1153
1208
  }
1209
+ function buildDirectoryTree(entryCount) {
1210
+ const links = /* @__PURE__ */ new Map();
1211
+ let redLevel = 0;
1212
+ for (let remaining = entryCount - 2; remaining >= 0; remaining = Math.floor(remaining / 2) - 1)
1213
+ redLevel++;
1214
+ const build = (low, high, level) => {
1215
+ if (low > high)
1216
+ return 4294967295;
1217
+ const id = Math.floor((low + high) / 2);
1218
+ links.set(id, {
1219
+ left: build(low, id - 1, level + 1),
1220
+ right: build(id + 1, high, level + 1),
1221
+ color: level === redLevel ? 0 : 1
1222
+ });
1223
+ return id;
1224
+ };
1225
+ return { root: build(1, entryCount - 1, 0), links };
1226
+ }
1154
1227
  function writeFatChain(fat, chain) {
1155
1228
  for (let i = 0; i < chain.sectors.length; i++) {
1156
1229
  fat[chain.sectors[i]] = i < chain.sectors.length - 1 ? chain.sectors[i + 1] : ENDOFCHAIN;
@@ -1174,7 +1247,7 @@ function writeInt32Sectors(outBytes, int32Data, firstSector, numSectors, sectorS
1174
1247
  }
1175
1248
  }
1176
1249
 
1177
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
1250
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write-serialize.js
1178
1251
  function writeHeader(outView, outBytes, params) {
1179
1252
  outBytes.set(OLE_MAGIC, 0);
1180
1253
  outView.setUint16(24, 62, true);
@@ -1232,6 +1305,7 @@ function writeDifatSectors(outView, params) {
1232
1305
  function serializeDirectoryEntries(dirEntries, numDirSectors, sectorSize) {
1233
1306
  const dirData = new Uint8Array(numDirSectors * sectorSize);
1234
1307
  const dirView = new DataView(dirData.buffer);
1308
+ const tree = buildDirectoryTree(dirEntries.length);
1235
1309
  for (let i = 0; i < dirEntries.length; i++) {
1236
1310
  const entry = dirEntries[i];
1237
1311
  const entryOffset = i * DIR_ENTRY_SIZE;
@@ -1239,17 +1313,17 @@ function serializeDirectoryEntries(dirEntries, numDirSectors, sectorSize) {
1239
1313
  dirData.set(nameBytes.subarray(0, Math.min(nameBytes.length, 64)), entryOffset);
1240
1314
  dirView.setUint16(entryOffset + 64, Math.min((entry.name.length + 1) * 2, 64), true);
1241
1315
  dirData[entryOffset + 66] = entry.type;
1242
- dirData[entryOffset + 67] = 1;
1316
+ dirData[entryOffset + 67] = i === 0 ? 1 : tree.links.get(i).color;
1243
1317
  if (entry.clsid) {
1244
1318
  dirData.set(entry.clsid.subarray(0, 16), entryOffset + 80);
1245
1319
  }
1246
1320
  if (i === 0) {
1247
1321
  dirView.setUint32(entryOffset + 68, 4294967295, true);
1248
1322
  dirView.setUint32(entryOffset + 72, 4294967295, true);
1249
- dirView.setUint32(entryOffset + 76, dirEntries.length > 1 ? 1 : 4294967295, true);
1323
+ dirView.setUint32(entryOffset + 76, tree.root, true);
1250
1324
  } else {
1251
- dirView.setUint32(entryOffset + 68, 4294967295, true);
1252
- dirView.setUint32(entryOffset + 72, i + 1 < dirEntries.length ? i + 1 : 4294967295, true);
1325
+ dirView.setUint32(entryOffset + 68, tree.links.get(i).left, true);
1326
+ dirView.setUint32(entryOffset + 72, tree.links.get(i).right, true);
1253
1327
  dirView.setUint32(entryOffset + 76, 4294967295, true);
1254
1328
  }
1255
1329
  dirView.setUint32(entryOffset + 116, entry.startSector, true);
@@ -1266,10 +1340,23 @@ function writeStreamSectors(outBytes, streamData, chain, sectorSize) {
1266
1340
  }
1267
1341
  }
1268
1342
 
1269
- // node_modules/.bun/@christophervr+ole2@0.4.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
1343
+ // node_modules/.bun/@christophervr+ole2@0.8.0/node_modules/@christophervr/ole2/dist/ole2-parser-write.js
1270
1344
  function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
1271
1345
  const sectorSize = 512;
1272
1346
  const miniSectorSize = 64;
1347
+ const names = [...streams2.keys()].sort(compareDirEntryNames);
1348
+ for (let i = 0; i < names.length; i++) {
1349
+ const name = names[i];
1350
+ if (name.toUpperCase().length !== name.length) {
1351
+ throw new Error("CFB stream names with expanding uppercase mappings are unsupported");
1352
+ }
1353
+ if (!name.length || name.length > 31 || /[\x00\\/:!]/.test(name)) {
1354
+ throw new Error("CFB stream names must be 1-31 UTF-16 code units without NUL, \\, /, :, or !");
1355
+ }
1356
+ if (i > 0 && compareDirEntryNames(names[i - 1], name) === 0) {
1357
+ throw new Error("Duplicate CFB stream names");
1358
+ }
1359
+ }
1273
1360
  const regularStreams = [];
1274
1361
  const miniStreams = [];
1275
1362
  for (const [name, data] of streams2) {
@@ -1287,7 +1374,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
1287
1374
  for (let i = 0; i < numSectors; i++) {
1288
1375
  sectors.push(nextSector++);
1289
1376
  }
1290
- fatChains.set(stream.name, { start: sectors[0] ?? 0, sectors });
1377
+ fatChains.set(stream.name, { start: sectors[0] ?? ENDOFCHAIN, sectors });
1291
1378
  }
1292
1379
  let miniStreamContainer = new Uint8Array(0);
1293
1380
  const miniFatChains = /* @__PURE__ */ new Map();
@@ -1310,7 +1397,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
1310
1397
  miniOffset += miniSectorSize;
1311
1398
  }
1312
1399
  miniFatChains.set(stream.name, {
1313
- start: miniSectors[0] ?? 0,
1400
+ start: miniSectors[0] ?? ENDOFCHAIN,
1314
1401
  sectors: miniSectors
1315
1402
  });
1316
1403
  }
@@ -1358,7 +1445,7 @@ function buildOle2(streams2, rootClsid, miniStreamCutoff = 4096) {
1358
1445
  nextSector += numDirSectors;
1359
1446
  let firstMiniFATSector = ENDOFCHAIN;
1360
1447
  let numMiniFATSectors = 0;
1361
- if (miniStreams.length > 0) {
1448
+ if (nextMiniSector > 0) {
1362
1449
  numMiniFATSectors = Math.ceil(nextMiniSector * 4 / sectorSize);
1363
1450
  firstMiniFATSector = nextSector;
1364
1451
  nextSector += numMiniFATSectors;