{"version":3,"file":"writer-IyFccCRJ.mjs","names":["ZIP32_MAX_ENTRIES"],"sources":["../src/zip/zip64-patch.ts","../src/zip/writer.ts"],"sourcesContent":["// ZIP64 post-processing for archives whose entry count exceeds the\n// 16-bit ZIP32 cap (65535). fflate's `Zip` writer always emits a\n// plain ZIP32 EOCD; for archives with more entries we keep its\n// per-entry LFH/CDH layout (correct as long as no individual size or\n// offset overflows 32 bits) and splice in a ZIP64 End-of-Central-\n// Directory record + locator before the EOCD, then patch the EOCD's\n// entry-count fields with the 0xFFFF sentinel that signals \"consult\n// the ZIP64 record for the real values\".\n//\n// The input is fflate's *final* chunk — the trailing [CD | EOCD] block\n// it emits in one ondata callback when `Zip.end()` is called. The\n// preceding entry-data chunks have already been streamed to the sink,\n// so we operate on the final chunk in isolation. The global EOCD\n// offset (needed for the ZIP64 locator) is derivable from cd_offset +\n// cd_size carried in the EOCD itself, so no external bookkeeping is\n// required.\n//\n// Out of scope: per-entry sizes or central-directory offsets > 4 GiB.\n// xlsx archives don't approach those limits in practice; we throw a\n// clear error if we detect overflow there.\n\nimport { OpenXmlIoError, OpenXmlNotImplementedError } from '../utils/exceptions';\n\nconst ZIP32_MAX_ENTRIES = 0xffff;\nconst ZIP32_MAX_U32 = 0xffffffff;\nconst SIG_EOCD = 0x06054b50;\nconst SIG_ZIP64_EOCD = 0x06064b50;\nconst SIG_ZIP64_EOCD_LOCATOR = 0x07064b50;\n\nconst ZIP64_EOCD_SIZE = 56;\nconst ZIP64_LOCATOR_SIZE = 20;\n\nconst u16 = (b: Uint8Array, o: number): number => (b[o] ?? 0) | ((b[o + 1] ?? 0) << 8);\n\nconst u32 = (b: Uint8Array, o: number): number => {\n  const v0 = b[o] ?? 0;\n  const v1 = b[o + 1] ?? 0;\n  const v2 = b[o + 2] ?? 0;\n  const v3 = b[o + 3] ?? 0;\n  return (v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)) >>> 0;\n};\n\nconst writeU16 = (b: Uint8Array, o: number, v: number): void => {\n  b[o] = v & 0xff;\n  b[o + 1] = (v >>> 8) & 0xff;\n};\n\nconst writeU32 = (b: Uint8Array, o: number, v: number): void => {\n  b[o] = v & 0xff;\n  b[o + 1] = (v >>> 8) & 0xff;\n  b[o + 2] = (v >>> 16) & 0xff;\n  b[o + 3] = (v >>> 24) & 0xff;\n};\n\nconst writeU64 = (b: Uint8Array, o: number, v: number): void => {\n  // JS Number safely represents integers up to 2^53 - 1, well beyond\n  // anything we'd ever emit here. Split via Math.floor + modulo to\n  // avoid bit-shift truncation at 32 bits.\n  const lo = v >>> 0;\n  const hi = Math.floor(v / 0x100000000) >>> 0;\n  writeU32(b, o, lo);\n  writeU32(b, o + 4, hi);\n};\n\nconst findEocdOffset = (bytes: Uint8Array): number => {\n  // EOCD is min 22 bytes and may be followed by up to 65535 bytes of\n  // archive comment. Scan backwards from the latest possible position.\n  const minOffset = Math.max(0, bytes.length - (22 + 0xffff));\n  for (let p = bytes.length - 22; p >= minOffset; p--) {\n    if (u32(bytes, p) === SIG_EOCD) {\n      const commentLen = u16(bytes, p + 20);\n      if (p + 22 + commentLen === bytes.length) return p;\n    }\n  }\n  throw new OpenXmlIoError('zip64-patch: no End-of-Central-Directory signature found');\n};\n\n/**\n * Splice ZIP64 EOCD record + locator into fflate's final chunk and\n * patch the trailing EOCD entry-count fields with the 0xFFFF sentinel.\n *\n * `finalChunk` must be the [CD | EOCD] block fflate emits as its last\n * ondata callback (everything before it is per-entry LFH/data/DD that\n * we leave untouched). Returns a new chunk; the input is not mutated.\n *\n * Assumes per-entry sizes and central-directory offset fit in 32 bits;\n * throws if not (xlsx archives never approach those limits).\n */\nexport function applyZip64EntryCountPatch(finalChunk: Uint8Array, totalEntries: number): Uint8Array {\n  if (totalEntries <= ZIP32_MAX_ENTRIES) return finalChunk;\n\n  const eocdOffset = findEocdOffset(finalChunk);\n\n  const cdSize = u32(finalChunk, eocdOffset + 12);\n  const cdOffset = u32(finalChunk, eocdOffset + 16);\n  const commentLen = u16(finalChunk, eocdOffset + 20);\n\n  if (cdSize === ZIP32_MAX_U32 || cdOffset === ZIP32_MAX_U32) {\n    throw new OpenXmlNotImplementedError(\n      'zip64-patch: archive size or central-directory offset exceeds 4 GiB; full ZIP64 size support is not implemented (xlsx in practice stays well under 4 GiB).',\n    );\n  }\n\n  // Where the EOCD starts in the *global* archive (before our patch).\n  // CD precedes EOCD with no gap, so global EOCD offset is just\n  // cd_offset + cd_size — the locator points here.\n  const globalEocdOffset = cdOffset + cdSize;\n\n  const eocdLen = 22 + commentLen;\n  const newChunkLen = eocdOffset + ZIP64_EOCD_SIZE + ZIP64_LOCATOR_SIZE + eocdLen;\n  const out = new Uint8Array(newChunkLen);\n\n  // Original CD bytes (everything before the EOCD).\n  out.set(finalChunk.subarray(0, eocdOffset), 0);\n\n  // ZIP64 EOCD record (56 bytes total).\n  const zip64Eocd = out.subarray(eocdOffset, eocdOffset + ZIP64_EOCD_SIZE);\n  writeU32(zip64Eocd, 0, SIG_ZIP64_EOCD);\n  // size_of_zip64_eocd = total_size - 12 (size field excludes signature + this field itself)\n  writeU64(zip64Eocd, 4, ZIP64_EOCD_SIZE - 12);\n  writeU16(zip64Eocd, 12, 45); // version made by (4.5 — first ZIP64 spec)\n  writeU16(zip64Eocd, 14, 45); // version needed\n  writeU32(zip64Eocd, 16, 0); // disk_number\n  writeU32(zip64Eocd, 20, 0); // disk_with_cd\n  writeU64(zip64Eocd, 24, totalEntries); // entries_on_this_disk\n  writeU64(zip64Eocd, 32, totalEntries); // total_entries\n  writeU64(zip64Eocd, 40, cdSize); // cd_size\n  writeU64(zip64Eocd, 48, cdOffset); // cd_offset\n\n  // ZIP64 EOCD locator (20 bytes).\n  const locOffset = eocdOffset + ZIP64_EOCD_SIZE;\n  const locator = out.subarray(locOffset, locOffset + ZIP64_LOCATOR_SIZE);\n  writeU32(locator, 0, SIG_ZIP64_EOCD_LOCATOR);\n  writeU32(locator, 4, 0); // disk_with_zip64_eocd\n  writeU64(locator, 8, globalEocdOffset);\n  writeU32(locator, 16, 1); // total_disks\n\n  // New EOCD: copy original then patch entry counts to the 0xFFFF\n  // sentinel. (fflate writes the low 16 bits of the true count there,\n  // which confuses readers that don't first look for the ZIP64 record.)\n  const newEocdOffset = locOffset + ZIP64_LOCATOR_SIZE;\n  out.set(finalChunk.subarray(eocdOffset, eocdOffset + eocdLen), newEocdOffset);\n  writeU16(out, newEocdOffset + 8, ZIP32_MAX_ENTRIES);\n  writeU16(out, newEocdOffset + 10, ZIP32_MAX_ENTRIES);\n\n  return out;\n}\n","// ZIP write layer. Streaming-deflate via fflate's `Zip` + per-entry\n// `ZipDeflate` / `ZipPassThrough` so the writer never holds the whole archive\n// in memory. Each addEntry pushes its bytes through the deflate stream and the\n// resulting ZIP chunks land on the sink one at a time — the buffered\n// `toBytes()` sink concatenates them on finish, while a streaming sink can\n// flush them as they arrive.\n//\n// ZIP64 (entry count > 65535): fflate's `Zip` emits a plain ZIP32 EOCD in all\n// cases, so on finalize we splice in a ZIP64 EOCD record + locator when needed\n// via `applyZip64EntryCountPatch`. That keeps the per-entry LFH/CDH layout\n// fflate produces and only rewrites the trailing records.\n//\n// Scope: this covers the entry-count-overflow case (the limit xlsx archives\n// realistically hit — `tens of millions of cells` → tens of thousands of\n// worksheet entries via the streaming writer). Per-entry compressed/uncompressed\n// sizes and the central-directory offset must still fit in 32 bits (≤ 4 GiB\n// each); a single >4 GiB entry would need full ZIP64 size support and\n// `applyZip64EntryCountPatch` throws `OpenXmlNotImplementedError` if we ever\n// detect that. xlsx workbooks don't approach that limit in practice, but the\n// constraint is real — surface it in your own size estimates.\n\nimport { Zip, ZipDeflate, ZipPassThrough } from 'fflate';\nimport type { XlsxSink } from '../io/sink';\nimport { OpenXmlIoError } from '../utils/exceptions';\nimport { applyZip64EntryCountPatch } from './zip64-patch';\n\nconst ZIP32_MAX_ENTRIES = 0xffff;\n\nexport interface ZipWriter {\n  /**\n   * Stage an entry. Bytes are pushed through fflate's `ZipDeflate` /\n   * `ZipPassThrough` stream synchronously, so the deflated chunks land on the\n   * sink as the call runs (no per-entry buffering — see the streaming-behaviour\n   * test in `tests/phase-1/zip/writer.test.ts`). Streams (`ReadableStream`)\n   * are not accepted today; pass an already-materialised entry, or use\n   * {@link addStreamingEntry} for chunked writes.\n   *\n   * `compress` defaults to `true`. Pass `false` for already-compressed payloads\n   * (PNG/JPEG/zip-as-binary content like vbaProject.bin) so we don't pay\n   * deflate costs for no gain.\n   */\n  addEntry(path: string, bytes: Uint8Array | ReadableStream<Uint8Array>, opts?: { compress?: boolean }): Promise<void>;\n\n  /**\n   * Open a streaming entry. Returns a writer the caller can `write()` chunks to\n   * and `end()` to seal the entry. Each chunk pushes through the same fflate\n   * `ZipDeflate` / `ZipPassThrough` machinery as `addEntry`, so peak memory\n   * stays at one chunk + deflate scratch even for multi-GB worksheets.\n   *\n   * Sequencing: only one streaming entry may be open at a time — `addEntry` and\n   * a second `addStreamingEntry` both throw until the current entry's `end()`\n   * resolves.\n   */\n  addStreamingEntry(path: string, opts?: { compress?: boolean }): StreamingEntryWriter;\n\n  /**\n   * Build the central directory and flush all bytes through the sink.\n   * Idempotent; subsequent calls resolve to the same payload.\n   */\n  finalize(): Promise<Uint8Array>;\n\n  /**\n   * Release the sink and underlying writer without producing a valid archive.\n   * Use this from a surrounding catch block when serialization fails part-way\n   * through — without it, streaming sinks (`toFile` / `toWritable`) keep their\n   * file descriptors / writables open and the half-written xlsx looks valid on\n   * disk. Idempotent; safe to call after `finalize()`.\n   */\n  abort(cause?: unknown): void;\n}\n\n/** Writer handle for a single streaming entry. */\nexport interface StreamingEntryWriter {\n  /** Push a chunk of bytes (already-encoded). Throws after `end()`. */\n  write(chunk: Uint8Array): void;\n  /** Seal the entry. Subsequent `write()` throws. Idempotent. */\n  end(): Promise<void>;\n}\n\n/**\n * ZIP writer backed by fflate's streaming `Zip` class. Entries are pushed\n * through `ZipDeflate` / `ZipPassThrough` streams as they arrive, so peak\n * memory stays at the size of the in-flight entry plus the output buffer rather\n * than the full archive.\n *\n * The sink contract is `toBytes()`, but that name is historical: the sink is\n * driven by a chunked `write(chunk)` API that fans bytes out as they arrive.\n * The buffered Node/browser sinks (`toBuffer`, `toBlob`, `toArrayBuffer`)\n * concatenate the chunks for a single-shot result; streaming sinks\n * (`toFile`, `toWritable`) forward each chunk to disk / the wrapped writable\n * without ever holding the full archive resident. Either kind plugs in here.\n */\nexport function createZipWriter(sink: XlsxSink): ZipWriter {\n  const writer = sink.toBytes();\n  let finalised: Promise<Uint8Array> | undefined;\n  let endCalled = false;\n  const seen = new Set<string>();\n  const errors: Error[] = [];\n  // fflate emits the [CD | EOCD] block in a single ondata call with\n  // `final=true`. We capture only that chunk so we can apply the ZIP64 patch on\n  // finalize; all preceding entry-data chunks stream straight to the sink to\n  // preserve the writer's incremental flushing contract.\n  let finalChunk: Uint8Array | undefined;\n  let zipFinishResolve: (() => void) | undefined;\n  const zipFinishPromise = new Promise<void>((resolve) => {\n    zipFinishResolve = resolve;\n  });\n\n  const zip = new Zip((err, chunk, final) => {\n    if (err) {\n      errors.push(err instanceof Error ? err : new Error(String(err)));\n      return;\n    }\n    // ZipDeflate emits an empty trailer chunk on the final callback even when\n    // there are no bytes; guard against pushing an undefined chunk.\n    if (chunk && chunk.byteLength > 0) {\n      if (final) {\n        // Buffer the trailing CD + EOCD block; written after possible patch.\n        finalChunk = chunk;\n      } else {\n        writer.write(chunk);\n      }\n    }\n    if (final && zipFinishResolve) {\n      zipFinishResolve();\n      zipFinishResolve = undefined;\n    }\n  });\n\n  let streamingOpen = false;\n\n  const guardAdd = (path: string): void => {\n    if (finalised !== undefined) {\n      throw new OpenXmlIoError('createZipWriter: addEntry after finalize');\n    }\n    if (streamingOpen) {\n      throw new OpenXmlIoError('createZipWriter: a streaming entry is still open — call end() first');\n    }\n    if (seen.has(path)) {\n      throw new OpenXmlIoError(`createZipWriter: duplicate entry \"${path}\"`);\n    }\n  };\n\n  return {\n    async addEntry(path, bytes, opts) {\n      if (!(bytes instanceof Uint8Array)) {\n        throw new OpenXmlIoError(\n          'createZipWriter: ReadableStream entries are not yet supported (deferred to streaming writer)',\n        );\n      }\n      guardAdd(path);\n      seen.add(path);\n      const compress = opts?.compress ?? true;\n      const file = compress ? new ZipDeflate(path) : new ZipPassThrough(path);\n      try {\n        zip.add(file);\n        file.push(bytes, /* final */ true);\n      } catch (cause) {\n        throw new OpenXmlIoError(`createZipWriter: failed to add entry \"${path}\"`, { cause });\n      }\n      if (errors.length > 0) {\n        throw new OpenXmlIoError('createZipWriter: stream error during addEntry', { cause: errors[0] });\n      }\n    },\n\n    addStreamingEntry(path, opts) {\n      guardAdd(path);\n      seen.add(path);\n      streamingOpen = true;\n      const compress = opts?.compress ?? true;\n      const file = compress ? new ZipDeflate(path) : new ZipPassThrough(path);\n      try {\n        zip.add(file);\n      } catch (cause) {\n        streamingOpen = false;\n        throw new OpenXmlIoError(`createZipWriter: failed to open streaming entry \"${path}\"`, { cause });\n      }\n      let ended = false;\n      return {\n        write(chunk: Uint8Array): void {\n          if (ended) throw new OpenXmlIoError(`createZipWriter: write after end on \"${path}\"`);\n          if (!(chunk instanceof Uint8Array)) {\n            throw new OpenXmlIoError(`createZipWriter: streaming entry \"${path}\" chunk is not a Uint8Array`);\n          }\n          if (chunk.byteLength === 0) return;\n          try {\n            file.push(chunk, /* final */ false);\n          } catch (cause) {\n            throw new OpenXmlIoError(`createZipWriter: failed to push chunk on \"${path}\"`, { cause });\n          }\n          if (errors.length > 0) {\n            throw new OpenXmlIoError('createZipWriter: stream error during write', { cause: errors[0] });\n          }\n        },\n        async end(): Promise<void> {\n          if (ended) return;\n          ended = true;\n          try {\n            file.push(new Uint8Array(0), /* final */ true);\n          } catch (cause) {\n            throw new OpenXmlIoError(`createZipWriter: failed to end streaming entry \"${path}\"`, { cause });\n          }\n          streamingOpen = false;\n          if (errors.length > 0) {\n            throw new OpenXmlIoError('createZipWriter: stream error during end', { cause: errors[0] });\n          }\n        },\n      };\n    },\n\n    async finalize() {\n      if (finalised !== undefined) return finalised;\n      if (streamingOpen) {\n        throw new OpenXmlIoError('createZipWriter: cannot finalize while a streaming entry is open');\n      }\n      finalised = (async () => {\n        try {\n          if (!endCalled) {\n            zip.end();\n            endCalled = true;\n          }\n        } catch (cause) {\n          throw new OpenXmlIoError('createZipWriter: failed to finalize zip archive', { cause });\n        }\n        await zipFinishPromise;\n        if (errors.length > 0) {\n          throw new OpenXmlIoError('createZipWriter: stream error during finalize', { cause: errors[0] });\n        }\n\n        // Apply the ZIP64 patch to fflate's [CD | EOCD] tail when the entry\n        // count exceeds ZIP32's 16-bit cap, then flush the (possibly patched)\n        // tail to the sink.\n        if (finalChunk) {\n          const patched =\n            seen.size > ZIP32_MAX_ENTRIES\n              ? applyZip64EntryCountPatch(finalChunk, seen.size)\n              : finalChunk;\n          writer.write(patched);\n        }\n        return writer.finish();\n      })();\n      return finalised;\n    },\n\n    abort(cause?: unknown): void {\n      if (finalised !== undefined) return;\n      // Mark finalised so any subsequent addEntry / finalize short-circuits.\n      finalised = Promise.resolve(new Uint8Array(0));\n      // Drop fflate's listener — we don't care about further `ondata` callbacks.\n      if (zipFinishResolve) {\n        zipFinishResolve();\n        zipFinishResolve = undefined;\n      }\n      writer.abort?.(cause);\n    },\n  };\n}\n"],"mappings":"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"}