@cj-tech-master/excelts 4.2.1 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +0 -31
- package/dist/browser/index.browser.d.ts +1 -0
- package/dist/browser/index.browser.js +12 -0
- package/dist/{esm/modules/archive → browser/modules/archive/compression}/compress.base.js +1 -1
- package/dist/{types/modules/archive → browser/modules/archive/compression}/compress.browser.d.ts +2 -8
- package/dist/browser/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
- package/dist/browser/modules/archive/{compress.d.ts → compression/compress.d.ts} +2 -2
- package/dist/{esm/modules/archive → browser/modules/archive/compression}/compress.js +1 -1
- package/dist/browser/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +1 -1
- package/dist/browser/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +1 -1
- package/dist/browser/modules/archive/{crc32.js → compression/crc32.js} +1 -1
- package/dist/browser/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
- package/dist/browser/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +2 -2
- package/dist/browser/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
- package/dist/browser/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +2 -2
- package/dist/browser/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
- package/dist/browser/modules/archive/defaults.d.ts +1 -0
- package/dist/browser/modules/archive/defaults.js +6 -3
- package/dist/browser/modules/archive/index.base.d.ts +4 -4
- package/dist/browser/modules/archive/index.base.js +3 -6
- package/dist/browser/modules/archive/index.browser.d.ts +3 -4
- package/dist/browser/modules/archive/index.browser.js +3 -7
- package/dist/browser/modules/archive/index.d.ts +3 -4
- package/dist/browser/modules/archive/index.js +3 -5
- package/dist/browser/modules/archive/internal/byte-queue.d.ts +33 -0
- package/dist/browser/modules/archive/internal/byte-queue.js +407 -0
- package/dist/browser/modules/archive/io/archive-sink.d.ts +8 -0
- package/dist/browser/modules/archive/io/archive-sink.js +45 -0
- package/dist/browser/modules/archive/io/archive-source.d.ts +6 -0
- package/dist/browser/modules/archive/io/archive-source.js +100 -0
- package/dist/browser/modules/archive/{extract.d.ts → unzip/extract.d.ts} +2 -2
- package/dist/browser/modules/archive/unzip/index.d.ts +40 -0
- package/dist/browser/modules/archive/unzip/index.js +164 -0
- package/dist/browser/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +36 -2
- package/dist/browser/modules/archive/unzip/stream.base.js +1022 -0
- package/dist/browser/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +1 -1
- package/dist/browser/modules/archive/{parse.browser.js → unzip/stream.browser.js} +371 -110
- package/dist/browser/modules/archive/{parse.d.ts → unzip/stream.d.ts} +2 -2
- package/dist/{esm/modules/archive/parse.js → browser/modules/archive/unzip/stream.js} +6 -5
- package/dist/browser/modules/archive/{zip-parser.d.ts → unzip/zip-parser.d.ts} +1 -1
- package/dist/{esm/modules/archive → browser/modules/archive/unzip}/zip-parser.js +38 -24
- package/dist/browser/modules/archive/utils/async-queue.d.ts +7 -0
- package/dist/browser/modules/archive/utils/async-queue.js +103 -0
- package/dist/browser/modules/archive/utils/bytes.js +16 -16
- package/dist/browser/modules/archive/utils/compressibility.d.ts +10 -0
- package/dist/browser/modules/archive/utils/compressibility.js +57 -0
- package/dist/browser/modules/archive/utils/parse-buffer.js +21 -23
- package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +21 -0
- package/dist/browser/modules/archive/utils/pattern-scanner.js +27 -0
- package/dist/browser/modules/archive/utils/timestamps.js +62 -1
- package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
- package/dist/browser/modules/archive/utils/zip-extra-fields.js +26 -14
- package/dist/browser/modules/archive/zip/index.d.ts +42 -0
- package/dist/browser/modules/archive/zip/index.js +157 -0
- package/dist/browser/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +28 -5
- package/dist/browser/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
- package/dist/browser/modules/archive/zip/zip-bytes.d.ts +73 -0
- package/dist/browser/modules/archive/zip/zip-bytes.js +239 -0
- package/dist/{esm/modules/archive → browser/modules/archive/zip}/zip-entry-metadata.js +3 -3
- package/dist/browser/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
- package/dist/browser/modules/archive/zip-spec/zip-records.js +126 -0
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
- package/dist/browser/modules/excel/utils/ooxml-validator.d.ts +48 -0
- package/dist/browser/modules/excel/utils/ooxml-validator.js +469 -0
- package/dist/browser/modules/excel/worksheet.js +5 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +3 -6
- package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
- package/dist/browser/modules/stream/base-transform.d.ts +3 -0
- package/dist/browser/modules/stream/base-transform.js +34 -20
- package/dist/browser/modules/stream/buffered-stream.d.ts +2 -12
- package/dist/browser/modules/stream/chunked-builder.js +4 -4
- package/dist/browser/modules/stream/index.browser.d.ts +13 -19
- package/dist/browser/modules/stream/index.browser.js +10 -22
- package/dist/browser/modules/stream/index.d.ts +18 -41
- package/dist/browser/modules/stream/index.js +15 -44
- package/dist/browser/modules/stream/internal/event-utils.d.ts +17 -0
- package/dist/browser/modules/stream/internal/event-utils.js +40 -0
- package/dist/browser/modules/stream/internal/type-guards.d.ts +9 -0
- package/dist/browser/modules/stream/internal/type-guards.js +24 -0
- package/dist/browser/modules/stream/pull-stream.d.ts +5 -6
- package/dist/browser/modules/stream/pull-stream.js +107 -43
- package/dist/browser/modules/stream/shared.d.ts +1 -1
- package/dist/browser/modules/stream/shared.js +7 -4
- package/dist/browser/modules/stream/streams.browser.d.ts +32 -44
- package/dist/browser/modules/stream/streams.browser.js +921 -836
- package/dist/browser/modules/stream/streams.d.ts +4 -20
- package/dist/browser/modules/stream/streams.js +146 -95
- package/dist/browser/modules/stream/utils.js +5 -38
- package/dist/cjs/modules/archive/{compress.base.js → compression/compress.base.js} +1 -1
- package/dist/cjs/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
- package/dist/cjs/modules/archive/{compress.js → compression/compress.js} +1 -1
- package/dist/cjs/modules/archive/{crc32.js → compression/crc32.js} +1 -1
- package/dist/cjs/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
- package/dist/cjs/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
- package/dist/cjs/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
- package/dist/cjs/modules/archive/defaults.js +7 -4
- package/dist/cjs/modules/archive/index.base.js +9 -19
- package/dist/cjs/modules/archive/index.browser.js +4 -10
- package/dist/cjs/modules/archive/index.js +4 -8
- package/dist/cjs/modules/archive/internal/byte-queue.js +411 -0
- package/dist/cjs/modules/archive/io/archive-sink.js +49 -0
- package/dist/cjs/modules/archive/io/archive-source.js +105 -0
- package/dist/cjs/modules/archive/unzip/index.js +170 -0
- package/dist/cjs/modules/archive/unzip/stream.base.js +1044 -0
- package/dist/cjs/modules/archive/{parse.browser.js → unzip/stream.browser.js} +372 -111
- package/dist/cjs/modules/archive/{parse.js → unzip/stream.js} +9 -8
- package/dist/cjs/modules/archive/{zip-parser.js → unzip/zip-parser.js} +47 -33
- package/dist/cjs/modules/archive/utils/async-queue.js +106 -0
- package/dist/cjs/modules/archive/utils/bytes.js +16 -16
- package/dist/cjs/modules/archive/utils/compressibility.js +60 -0
- package/dist/cjs/modules/archive/utils/parse-buffer.js +21 -23
- package/dist/cjs/modules/archive/utils/pattern-scanner.js +31 -0
- package/dist/cjs/modules/archive/utils/timestamps.js +64 -3
- package/dist/cjs/modules/archive/utils/zip-extra-fields.js +26 -14
- package/dist/cjs/modules/archive/zip/index.js +162 -0
- package/dist/cjs/modules/archive/{streaming-zip.js → zip/stream.js} +194 -50
- package/dist/cjs/modules/archive/zip/zip-bytes.js +242 -0
- package/dist/cjs/modules/archive/{zip-entry-metadata.js → zip/zip-entry-metadata.js} +5 -5
- package/dist/cjs/modules/archive/zip-spec/zip-records.js +136 -0
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
- package/dist/cjs/modules/excel/utils/ooxml-validator.js +475 -0
- package/dist/cjs/modules/excel/worksheet.js +5 -2
- package/dist/cjs/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/sp-xform.js +115 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/cjs/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +6 -9
- package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
- package/dist/cjs/modules/stream/base-transform.js +34 -20
- package/dist/cjs/modules/stream/chunked-builder.js +4 -4
- package/dist/cjs/modules/stream/index.browser.js +10 -17
- package/dist/cjs/modules/stream/index.js +15 -39
- package/dist/cjs/modules/stream/internal/event-utils.js +43 -0
- package/dist/cjs/modules/stream/internal/type-guards.js +30 -0
- package/dist/cjs/modules/stream/pull-stream.js +107 -43
- package/dist/cjs/modules/stream/shared.js +7 -4
- package/dist/cjs/modules/stream/streams.browser.js +927 -847
- package/dist/cjs/modules/stream/streams.js +156 -107
- package/dist/cjs/modules/stream/utils.js +3 -36
- package/dist/esm/index.browser.js +12 -0
- package/dist/{browser/modules/archive → esm/modules/archive/compression}/compress.base.js +1 -1
- package/dist/esm/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
- package/dist/{browser/modules/archive → esm/modules/archive/compression}/compress.js +1 -1
- package/dist/esm/modules/archive/{crc32.js → compression/crc32.js} +1 -1
- package/dist/esm/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
- package/dist/esm/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
- package/dist/esm/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
- package/dist/esm/modules/archive/defaults.js +6 -3
- package/dist/esm/modules/archive/index.base.js +3 -6
- package/dist/esm/modules/archive/index.browser.js +3 -7
- package/dist/esm/modules/archive/index.js +3 -5
- package/dist/esm/modules/archive/internal/byte-queue.js +407 -0
- package/dist/esm/modules/archive/io/archive-sink.js +45 -0
- package/dist/esm/modules/archive/io/archive-source.js +100 -0
- package/dist/esm/modules/archive/unzip/index.js +164 -0
- package/dist/esm/modules/archive/unzip/stream.base.js +1022 -0
- package/dist/esm/modules/archive/{parse.browser.js → unzip/stream.browser.js} +371 -110
- package/dist/{browser/modules/archive/parse.js → esm/modules/archive/unzip/stream.js} +6 -5
- package/dist/{browser/modules/archive → esm/modules/archive/unzip}/zip-parser.js +38 -24
- package/dist/esm/modules/archive/utils/async-queue.js +103 -0
- package/dist/esm/modules/archive/utils/bytes.js +16 -16
- package/dist/esm/modules/archive/utils/compressibility.js +57 -0
- package/dist/esm/modules/archive/utils/parse-buffer.js +21 -23
- package/dist/esm/modules/archive/utils/pattern-scanner.js +27 -0
- package/dist/esm/modules/archive/utils/timestamps.js +62 -1
- package/dist/esm/modules/archive/utils/zip-extra-fields.js +26 -14
- package/dist/esm/modules/archive/zip/index.js +157 -0
- package/dist/esm/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
- package/dist/esm/modules/archive/zip/zip-bytes.js +239 -0
- package/dist/{browser/modules/archive → esm/modules/archive/zip}/zip-entry-metadata.js +3 -3
- package/dist/esm/modules/archive/zip-spec/zip-records.js +126 -0
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
- package/dist/esm/modules/excel/utils/ooxml-validator.js +469 -0
- package/dist/esm/modules/excel/worksheet.js +5 -2
- package/dist/esm/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
- package/dist/esm/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +3 -6
- package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
- package/dist/esm/modules/stream/base-transform.js +34 -20
- package/dist/esm/modules/stream/chunked-builder.js +4 -4
- package/dist/esm/modules/stream/index.browser.js +10 -22
- package/dist/esm/modules/stream/index.js +15 -44
- package/dist/esm/modules/stream/internal/event-utils.js +40 -0
- package/dist/esm/modules/stream/internal/type-guards.js +24 -0
- package/dist/esm/modules/stream/pull-stream.js +107 -43
- package/dist/esm/modules/stream/shared.js +7 -4
- package/dist/esm/modules/stream/streams.browser.js +921 -836
- package/dist/esm/modules/stream/streams.js +146 -95
- package/dist/esm/modules/stream/utils.js +5 -38
- package/dist/iife/THIRD_PARTY_NOTICES.md +0 -31
- package/dist/iife/excelts.iife.js +6495 -4440
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +103 -31
- package/dist/types/index.browser.d.ts +1 -0
- package/dist/{browser/modules/archive → types/modules/archive/compression}/compress.browser.d.ts +2 -8
- package/dist/types/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +1 -1
- package/dist/types/modules/archive/defaults.d.ts +1 -0
- package/dist/types/modules/archive/index.base.d.ts +4 -4
- package/dist/types/modules/archive/index.browser.d.ts +3 -4
- package/dist/types/modules/archive/index.d.ts +3 -4
- package/dist/types/modules/archive/internal/byte-queue.d.ts +33 -0
- package/dist/types/modules/archive/io/archive-sink.d.ts +8 -0
- package/dist/types/modules/archive/io/archive-source.d.ts +6 -0
- package/dist/types/modules/archive/unzip/index.d.ts +40 -0
- package/dist/types/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +38 -4
- package/dist/types/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +2 -2
- package/dist/types/modules/archive/{parse.d.ts → unzip/stream.d.ts} +3 -3
- package/dist/types/modules/archive/{zip-parser.d.ts → unzip/zip-parser.d.ts} +1 -1
- package/dist/types/modules/archive/utils/async-queue.d.ts +7 -0
- package/dist/types/modules/archive/utils/compressibility.d.ts +10 -0
- package/dist/types/modules/archive/utils/pattern-scanner.d.ts +21 -0
- package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
- package/dist/types/modules/archive/zip/index.d.ts +42 -0
- package/dist/types/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +29 -6
- package/dist/types/modules/archive/zip/zip-bytes.d.ts +73 -0
- package/dist/types/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +1 -1
- package/dist/types/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
- package/dist/types/modules/excel/utils/ooxml-validator.d.ts +48 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
- package/dist/types/modules/stream/base-transform.d.ts +3 -0
- package/dist/types/modules/stream/buffered-stream.d.ts +2 -12
- package/dist/types/modules/stream/index.browser.d.ts +13 -19
- package/dist/types/modules/stream/index.d.ts +18 -41
- package/dist/types/modules/stream/internal/event-utils.d.ts +17 -0
- package/dist/types/modules/stream/internal/type-guards.d.ts +9 -0
- package/dist/types/modules/stream/pull-stream.d.ts +5 -6
- package/dist/types/modules/stream/shared.d.ts +1 -1
- package/dist/types/modules/stream/streams.browser.d.ts +32 -44
- package/dist/types/modules/stream/streams.d.ts +4 -20
- package/package.json +14 -10
- package/dist/browser/modules/archive/byte-queue.d.ts +0 -18
- package/dist/browser/modules/archive/byte-queue.js +0 -125
- package/dist/browser/modules/archive/parse.base.js +0 -644
- package/dist/browser/modules/archive/utils/zip-extra.d.ts +0 -18
- package/dist/browser/modules/archive/utils/zip-extra.js +0 -68
- package/dist/browser/modules/archive/zip-builder.d.ts +0 -117
- package/dist/browser/modules/archive/zip-builder.js +0 -292
- package/dist/browser/modules/archive/zip-constants.d.ts +0 -18
- package/dist/browser/modules/archive/zip-constants.js +0 -23
- package/dist/browser/modules/archive/zip-records.js +0 -84
- package/dist/cjs/modules/archive/byte-queue.js +0 -129
- package/dist/cjs/modules/archive/parse.base.js +0 -666
- package/dist/cjs/modules/archive/utils/zip-extra.js +0 -74
- package/dist/cjs/modules/archive/zip-builder.js +0 -297
- package/dist/cjs/modules/archive/zip-constants.js +0 -26
- package/dist/cjs/modules/archive/zip-records.js +0 -90
- package/dist/esm/modules/archive/byte-queue.js +0 -125
- package/dist/esm/modules/archive/parse.base.js +0 -644
- package/dist/esm/modules/archive/utils/zip-extra.js +0 -68
- package/dist/esm/modules/archive/zip-builder.js +0 -292
- package/dist/esm/modules/archive/zip-constants.js +0 -23
- package/dist/esm/modules/archive/zip-records.js +0 -84
- package/dist/types/modules/archive/byte-queue.d.ts +0 -18
- package/dist/types/modules/archive/utils/zip-extra.d.ts +0 -18
- package/dist/types/modules/archive/zip-builder.d.ts +0 -117
- package/dist/types/modules/archive/zip-constants.d.ts +0 -18
- /package/dist/browser/modules/archive/{compress.base.d.ts → compression/compress.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
- /package/dist/browser/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
- /package/dist/browser/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
- /package/dist/browser/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
- /package/dist/browser/modules/archive/{extract.js → unzip/extract.js} +0 -0
- /package/dist/browser/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +0 -0
- /package/dist/browser/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
- /package/dist/browser/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
- /package/dist/cjs/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
- /package/dist/cjs/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
- /package/dist/cjs/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
- /package/dist/cjs/modules/archive/{extract.js → unzip/extract.js} +0 -0
- /package/dist/cjs/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
- /package/dist/esm/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
- /package/dist/esm/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
- /package/dist/esm/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
- /package/dist/esm/modules/archive/{extract.js → unzip/extract.js} +0 -0
- /package/dist/esm/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
- /package/dist/types/modules/archive/{compress.base.d.ts → compression/compress.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{compress.d.ts → compression/compress.d.ts} +0 -0
- /package/dist/types/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +0 -0
- /package/dist/types/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +0 -0
- /package/dist/types/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
- /package/dist/types/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +0 -0
- /package/dist/types/modules/archive/{extract.d.ts → unzip/extract.d.ts} +0 -0
- /package/dist/types/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import zlib from "zlib";
|
|
2
|
-
import {
|
|
3
|
-
import { PullStream, runParseLoop, streamUntilValidatedDataDescriptor } from "./parse.base.js";
|
|
4
|
-
import { DATA_DESCRIPTOR_SIG } from "./zip-constants.js";
|
|
2
|
+
import { DATA_DESCRIPTOR_SIGNATURE_BYTES, PullStream, runParseLoop, streamUntilValidatedDataDescriptor } from "./stream.base.js";
|
|
5
3
|
/**
|
|
6
4
|
* Creates an InflateRaw stream using Node.js native zlib.
|
|
7
5
|
*/
|
|
8
6
|
function createInflateRaw() {
|
|
9
7
|
return zlib.createInflateRaw();
|
|
10
8
|
}
|
|
11
|
-
const dataDescriptorSignature =
|
|
9
|
+
const dataDescriptorSignature = DATA_DESCRIPTOR_SIGNATURE_BYTES;
|
|
12
10
|
export function createParseClass(createInflateRawFn) {
|
|
13
11
|
return class Parse extends PullStream {
|
|
14
12
|
constructor(opts = {}) {
|
|
@@ -63,9 +61,12 @@ export function createParseClass(createInflateRawFn) {
|
|
|
63
61
|
_streamUntilValidatedDataDescriptor() {
|
|
64
62
|
return streamUntilValidatedDataDescriptor({
|
|
65
63
|
source: {
|
|
66
|
-
getView: () => this._queue.view(),
|
|
67
64
|
getLength: () => this._queue.length,
|
|
68
65
|
read: (length) => this._queue.read(length),
|
|
66
|
+
peekChunks: (length) => this._queue.peekChunks(length),
|
|
67
|
+
discard: (length) => this._queue.discard(length),
|
|
68
|
+
indexOfPattern: (pattern, startIndex) => this._queue.indexOfPattern(pattern, startIndex),
|
|
69
|
+
peekUint32LE: (offset) => this._queue.peekUint32LE(offset),
|
|
69
70
|
isFinished: () => this.finished,
|
|
70
71
|
onDataAvailable: (cb) => {
|
|
71
72
|
this.on("chunk", cb);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Works in both Node.js and browser environments
|
|
4
4
|
* No dependency on Node.js stream module
|
|
5
5
|
*/
|
|
6
|
-
import type { ZipEntryInfo } from "@archive/zip-entry-info";
|
|
6
|
+
import type { ZipEntryInfo } from "@archive/zip-spec/zip-entry-info";
|
|
7
7
|
export type { ZipEntryInfo };
|
|
8
8
|
/**
|
|
9
9
|
* ZIP parsing options
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Works in both Node.js and browser environments
|
|
4
4
|
* No dependency on Node.js stream module
|
|
5
5
|
*/
|
|
6
|
-
import { decompress, decompressSync } from "
|
|
7
|
-
import { BinaryReader } from "
|
|
8
|
-
import { resolveZipLastModifiedDateFromUnixSeconds } from "
|
|
9
|
-
import { parseZipExtraFields } from "
|
|
10
|
-
import { CENTRAL_DIR_HEADER_SIG, COMPRESSION_DEFLATE, COMPRESSION_STORE,
|
|
6
|
+
import { decompress, decompressSync } from "../compression/compress.browser.js";
|
|
7
|
+
import { BinaryReader } from "../utils/binary.js";
|
|
8
|
+
import { resolveZipLastModifiedDateFromUnixSeconds } from "../utils/timestamps.js";
|
|
9
|
+
import { parseZipExtraFields } from "../utils/zip-extra-fields.js";
|
|
10
|
+
import { CENTRAL_DIR_HEADER_SIG, COMPRESSION_DEFLATE, COMPRESSION_STORE, LOCAL_FILE_HEADER_SIG, UINT16_MAX, UINT32_MAX, ZIP64_END_OF_CENTRAL_DIR_SIG } from "../zip-spec/zip-records.js";
|
|
11
11
|
/**
|
|
12
12
|
* Find the End of Central Directory record
|
|
13
13
|
* Searches backwards from the end of the file
|
|
@@ -16,9 +16,13 @@ function findEndOfCentralDir(data) {
|
|
|
16
16
|
// EOCD is at least 22 bytes, search backwards
|
|
17
17
|
// Comment can be up to 65535 bytes
|
|
18
18
|
const minOffset = Math.max(0, data.length - 65557);
|
|
19
|
-
|
|
19
|
+
// Signature bytes (little-endian): 0x06054b50 -> 50 4b 05 06
|
|
20
|
+
const b0 = 0x50;
|
|
21
|
+
const b1 = 0x4b;
|
|
22
|
+
const b2 = 0x05;
|
|
23
|
+
const b3 = 0x06;
|
|
20
24
|
for (let i = data.length - 22; i >= minOffset; i--) {
|
|
21
|
-
if (
|
|
25
|
+
if (data[i] === b0 && data[i + 1] === b1 && data[i + 2] === b2 && data[i + 3] === b3) {
|
|
22
26
|
return i;
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -33,8 +37,11 @@ function findZip64EOCDLocator(data, eocdOffset) {
|
|
|
33
37
|
if (locatorOffset < 0) {
|
|
34
38
|
return -1;
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
if (
|
|
40
|
+
// Signature bytes (little-endian): 0x07064b50 -> 50 4b 06 07
|
|
41
|
+
if (data[locatorOffset] === 0x50 &&
|
|
42
|
+
data[locatorOffset + 1] === 0x4b &&
|
|
43
|
+
data[locatorOffset + 2] === 0x06 &&
|
|
44
|
+
data[locatorOffset + 3] === 0x07) {
|
|
38
45
|
return locatorOffset;
|
|
39
46
|
}
|
|
40
47
|
return -1;
|
|
@@ -44,7 +51,7 @@ function findZip64EOCDLocator(data, eocdOffset) {
|
|
|
44
51
|
*/
|
|
45
52
|
function parseZipEntries(data, options = {}) {
|
|
46
53
|
const { decodeStrings = true } = options;
|
|
47
|
-
|
|
54
|
+
let entries = [];
|
|
48
55
|
// Find End of Central Directory
|
|
49
56
|
const eocdOffset = findEndOfCentralDir(data);
|
|
50
57
|
if (eocdOffset === -1) {
|
|
@@ -96,6 +103,10 @@ function parseZipEntries(data, options = {}) {
|
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
}
|
|
106
|
+
// Preallocate to avoid repeated array growth on large archives.
|
|
107
|
+
if (totalEntries > 0) {
|
|
108
|
+
entries = new Array(totalEntries);
|
|
109
|
+
}
|
|
99
110
|
// Read Central Directory entries
|
|
100
111
|
const centralReader = new BinaryReader(data, centralDirOffset);
|
|
101
112
|
for (let i = 0; i < totalEntries; i++) {
|
|
@@ -144,23 +155,26 @@ function parseZipEntries(data, options = {}) {
|
|
|
144
155
|
// Check for UTF-8 flag (bit 11)
|
|
145
156
|
const isUtf8 = (flags & 0x800) !== 0;
|
|
146
157
|
const useUtf8 = decodeStrings && isUtf8;
|
|
147
|
-
const fileName = centralReader.readString(fileNameLength, useUtf8);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
const fileName = fileNameLength > 0 ? centralReader.readString(fileNameLength, useUtf8) : "";
|
|
159
|
+
let extraFields = {};
|
|
160
|
+
if (extraFieldLength > 0) {
|
|
161
|
+
const extraField = centralReader.readBytes(extraFieldLength);
|
|
162
|
+
const vars = {
|
|
163
|
+
compressedSize,
|
|
164
|
+
uncompressedSize,
|
|
165
|
+
offsetToLocalFileHeader: localHeaderOffset
|
|
166
|
+
};
|
|
167
|
+
extraFields = parseZipExtraFields(extraField, vars);
|
|
168
|
+
compressedSize = vars.compressedSize;
|
|
169
|
+
uncompressedSize = vars.uncompressedSize;
|
|
170
|
+
localHeaderOffset = vars.offsetToLocalFileHeader ?? localHeaderOffset;
|
|
171
|
+
}
|
|
172
|
+
const comment = commentLength > 0 ? centralReader.readString(commentLength, useUtf8) : "";
|
|
159
173
|
const isDirectory = fileName.endsWith("/") || (externalAttributes & 0x10) !== 0;
|
|
160
174
|
const isEncrypted = (flags & 0x01) !== 0;
|
|
161
175
|
const unixSecondsMtime = extraFields.mtimeUnixSeconds;
|
|
162
176
|
const lastModified = resolveZipLastModifiedDateFromUnixSeconds(lastModDate, lastModTime, unixSecondsMtime);
|
|
163
|
-
entries
|
|
177
|
+
entries[i] = {
|
|
164
178
|
path: fileName,
|
|
165
179
|
isDirectory,
|
|
166
180
|
compressedSize,
|
|
@@ -172,7 +186,7 @@ function parseZipEntries(data, options = {}) {
|
|
|
172
186
|
comment,
|
|
173
187
|
externalAttributes,
|
|
174
188
|
isEncrypted
|
|
175
|
-
}
|
|
189
|
+
};
|
|
176
190
|
}
|
|
177
191
|
return entries;
|
|
178
192
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export function createAsyncQueue() {
|
|
2
|
+
const values = [];
|
|
3
|
+
let valuesHead = 0;
|
|
4
|
+
const waiters = [];
|
|
5
|
+
let waitersHead = 0;
|
|
6
|
+
let done = false;
|
|
7
|
+
let error = null;
|
|
8
|
+
const maybeCompact = () => {
|
|
9
|
+
// Prevent unbounded growth of the underlying arrays.
|
|
10
|
+
if (valuesHead > 1024 && valuesHead * 2 > values.length) {
|
|
11
|
+
values.splice(0, valuesHead);
|
|
12
|
+
valuesHead = 0;
|
|
13
|
+
}
|
|
14
|
+
if (waitersHead > 1024 && waitersHead * 2 > waiters.length) {
|
|
15
|
+
waiters.splice(0, waitersHead);
|
|
16
|
+
waitersHead = 0;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const shiftWaiter = () => {
|
|
20
|
+
while (waitersHead < waiters.length) {
|
|
21
|
+
const w = waiters[waitersHead];
|
|
22
|
+
waiters[waitersHead] = undefined;
|
|
23
|
+
waitersHead++;
|
|
24
|
+
if (w) {
|
|
25
|
+
maybeCompact();
|
|
26
|
+
return w;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
maybeCompact();
|
|
30
|
+
return undefined;
|
|
31
|
+
};
|
|
32
|
+
const shiftValue = () => {
|
|
33
|
+
while (valuesHead < values.length) {
|
|
34
|
+
const v = values[valuesHead];
|
|
35
|
+
values[valuesHead] = undefined;
|
|
36
|
+
valuesHead++;
|
|
37
|
+
if (v !== undefined) {
|
|
38
|
+
maybeCompact();
|
|
39
|
+
return v;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
maybeCompact();
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
45
|
+
const push = (value) => {
|
|
46
|
+
if (done || error) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const waiter = shiftWaiter();
|
|
50
|
+
if (waiter) {
|
|
51
|
+
waiter.resolve({ value, done: false });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
values.push(value);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const fail = (err) => {
|
|
58
|
+
if (done || error) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
error = err;
|
|
62
|
+
while (true) {
|
|
63
|
+
const waiter = shiftWaiter();
|
|
64
|
+
if (!waiter) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
waiter.reject(err);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const close = () => {
|
|
71
|
+
if (done || error) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
done = true;
|
|
75
|
+
while (true) {
|
|
76
|
+
const waiter = shiftWaiter();
|
|
77
|
+
if (!waiter) {
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
waiter.resolve({ value: undefined, done: true });
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const iterable = {
|
|
84
|
+
[Symbol.asyncIterator]() {
|
|
85
|
+
return {
|
|
86
|
+
next() {
|
|
87
|
+
if (error) {
|
|
88
|
+
return Promise.reject(error);
|
|
89
|
+
}
|
|
90
|
+
const value = shiftValue();
|
|
91
|
+
if (value !== undefined) {
|
|
92
|
+
return Promise.resolve({ value, done: false });
|
|
93
|
+
}
|
|
94
|
+
if (done) {
|
|
95
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
96
|
+
}
|
|
97
|
+
return new Promise((resolve, reject) => waiters.push({ resolve, reject }));
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return { push, fail, close, iterable };
|
|
103
|
+
}
|
|
@@ -45,21 +45,18 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
45
45
|
}
|
|
46
46
|
// Fast paths for small patterns (very common in ZIP parsing: 2/3/4-byte signatures).
|
|
47
47
|
if (patLen === 1) {
|
|
48
|
-
|
|
49
|
-
for (let i = start; i < bufLen; i++) {
|
|
50
|
-
if (buffer[i] === p0) {
|
|
51
|
-
return i;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return -1;
|
|
48
|
+
return buffer.indexOf(pattern[0], start);
|
|
55
49
|
}
|
|
56
50
|
if (patLen === 2) {
|
|
57
51
|
const p0 = pattern[0];
|
|
58
52
|
const p1 = pattern[1];
|
|
59
|
-
|
|
60
|
-
|
|
53
|
+
const last = bufLen - 2;
|
|
54
|
+
let i = buffer.indexOf(p0, start);
|
|
55
|
+
while (i !== -1 && i <= last) {
|
|
56
|
+
if (buffer[i + 1] === p1) {
|
|
61
57
|
return i;
|
|
62
58
|
}
|
|
59
|
+
i = buffer.indexOf(p0, i + 1);
|
|
63
60
|
}
|
|
64
61
|
return -1;
|
|
65
62
|
}
|
|
@@ -67,10 +64,13 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
67
64
|
const p0 = pattern[0];
|
|
68
65
|
const p1 = pattern[1];
|
|
69
66
|
const p2 = pattern[2];
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
const last = bufLen - 3;
|
|
68
|
+
let i = buffer.indexOf(p0, start);
|
|
69
|
+
while (i !== -1 && i <= last) {
|
|
70
|
+
if (buffer[i + 1] === p1 && buffer[i + 2] === p2) {
|
|
72
71
|
return i;
|
|
73
72
|
}
|
|
73
|
+
i = buffer.indexOf(p0, i + 1);
|
|
74
74
|
}
|
|
75
75
|
return -1;
|
|
76
76
|
}
|
|
@@ -79,13 +79,13 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
79
79
|
const p1 = pattern[1];
|
|
80
80
|
const p2 = pattern[2];
|
|
81
81
|
const p3 = pattern[3];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
buffer[i + 3] === p3) {
|
|
82
|
+
const last = bufLen - 4;
|
|
83
|
+
let i = buffer.indexOf(p0, start);
|
|
84
|
+
while (i !== -1 && i <= last) {
|
|
85
|
+
if (buffer[i + 1] === p1 && buffer[i + 2] === p2 && buffer[i + 3] === p3) {
|
|
87
86
|
return i;
|
|
88
87
|
}
|
|
88
|
+
i = buffer.indexOf(p0, i + 1);
|
|
89
89
|
}
|
|
90
90
|
return -1;
|
|
91
91
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic: detect incompressible (high-entropy) data.
|
|
3
|
+
*
|
|
4
|
+
* This is a performance optimization: if data looks random, DEFLATE usually
|
|
5
|
+
* wastes CPU and may even produce slightly larger output.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isProbablyIncompressible(data: Uint8Array, options?: {
|
|
8
|
+
sampleBytes?: number;
|
|
9
|
+
minDecisionBytes?: number;
|
|
10
|
+
}): boolean;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const DEFAULT_SAMPLE_BYTES = 64 * 1024;
|
|
2
|
+
const MIN_DECISION_BYTES = 16 * 1024;
|
|
3
|
+
function log2(x) {
|
|
4
|
+
return Math.log(x) / Math.LN2;
|
|
5
|
+
}
|
|
6
|
+
function shannonEntropy(bytes) {
|
|
7
|
+
const counts = new Uint32Array(256);
|
|
8
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
9
|
+
counts[bytes[i]] += 1;
|
|
10
|
+
}
|
|
11
|
+
let entropy = 0;
|
|
12
|
+
const total = bytes.length;
|
|
13
|
+
for (let i = 0; i < 256; i++) {
|
|
14
|
+
const count = counts[i];
|
|
15
|
+
if (count === 0) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const p = count / total;
|
|
19
|
+
entropy -= p * log2(p);
|
|
20
|
+
}
|
|
21
|
+
return entropy;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Heuristic: detect incompressible (high-entropy) data.
|
|
25
|
+
*
|
|
26
|
+
* This is a performance optimization: if data looks random, DEFLATE usually
|
|
27
|
+
* wastes CPU and may even produce slightly larger output.
|
|
28
|
+
*/
|
|
29
|
+
export function isProbablyIncompressible(data, options = {}) {
|
|
30
|
+
const sampleBytes = options.sampleBytes ?? DEFAULT_SAMPLE_BYTES;
|
|
31
|
+
const minDecisionBytes = options.minDecisionBytes ?? MIN_DECISION_BYTES;
|
|
32
|
+
const len = Math.min(data.length, sampleBytes);
|
|
33
|
+
if (len < minDecisionBytes) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const sample = data.subarray(0, len);
|
|
37
|
+
// Fast-ish early filter: if there are too few unique bytes, it's probably compressible.
|
|
38
|
+
// (e.g. text, repeated patterns)
|
|
39
|
+
const seen = new Uint8Array(256);
|
|
40
|
+
let unique = 0;
|
|
41
|
+
for (let i = 0; i < sample.length; i++) {
|
|
42
|
+
const b = sample[i];
|
|
43
|
+
if (seen[b] === 0) {
|
|
44
|
+
seen[b] = 1;
|
|
45
|
+
unique += 1;
|
|
46
|
+
if (unique >= 200) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (unique < 200) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
// Shannon entropy in bits/byte; random tends to ~8.
|
|
55
|
+
// Threshold picked to be conservative.
|
|
56
|
+
return shannonEntropy(sample) >= 7.95;
|
|
57
|
+
}
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Read unsigned little-endian integer from Uint8Array
|
|
3
|
-
*/
|
|
4
|
-
function readUIntLE(buffer, offset, size) {
|
|
5
|
-
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
6
|
-
switch (size) {
|
|
7
|
-
case 1:
|
|
8
|
-
return view.getUint8(offset);
|
|
9
|
-
case 2:
|
|
10
|
-
return view.getUint16(offset, true);
|
|
11
|
-
case 4:
|
|
12
|
-
return view.getUint32(offset, true);
|
|
13
|
-
case 8: {
|
|
14
|
-
// Read as BigUint64 and convert to Number
|
|
15
|
-
const low = view.getUint32(offset, true);
|
|
16
|
-
const high = view.getUint32(offset + 4, true);
|
|
17
|
-
return high * 0x100000000 + low;
|
|
18
|
-
}
|
|
19
|
-
default:
|
|
20
|
-
throw new Error("Unsupported UInt LE size!");
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
1
|
/**
|
|
24
2
|
* Parses sequential unsigned little endian numbers from the head of the passed buffer according to
|
|
25
3
|
* the specified format passed. If the buffer is not large enough to satisfy the full format,
|
|
@@ -38,10 +16,30 @@ function readUIntLE(buffer, offset, size) {
|
|
|
38
16
|
*/
|
|
39
17
|
export function parse(buffer, format) {
|
|
40
18
|
const result = {};
|
|
19
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
41
20
|
let offset = 0;
|
|
42
21
|
for (const [key, size] of format) {
|
|
43
22
|
if (buffer.length >= offset + size) {
|
|
44
|
-
|
|
23
|
+
switch (size) {
|
|
24
|
+
case 1:
|
|
25
|
+
result[key] = view.getUint8(offset);
|
|
26
|
+
break;
|
|
27
|
+
case 2:
|
|
28
|
+
result[key] = view.getUint16(offset, true);
|
|
29
|
+
break;
|
|
30
|
+
case 4:
|
|
31
|
+
result[key] = view.getUint32(offset, true);
|
|
32
|
+
break;
|
|
33
|
+
case 8: {
|
|
34
|
+
// Keep behavior (Number) while avoiding BigInt costs.
|
|
35
|
+
const low = view.getUint32(offset, true);
|
|
36
|
+
const high = view.getUint32(offset + 4, true);
|
|
37
|
+
result[key] = high * 0x100000000 + low;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
default:
|
|
41
|
+
throw new Error("Unsupported UInt LE size!");
|
|
42
|
+
}
|
|
45
43
|
}
|
|
46
44
|
else {
|
|
47
45
|
result[key] = null;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface PatternSearchTarget {
|
|
2
|
+
indexOfPattern(pattern: Uint8Array, startIndex: number): number;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Stateful helper for incremental pattern scanning in growing buffers.
|
|
6
|
+
*
|
|
7
|
+
* The scanner tracks a `searchFrom` cursor and an `overlap` region so callers
|
|
8
|
+
* can avoid rescanning bytes that cannot start a match.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PatternScanner {
|
|
11
|
+
readonly pattern: Uint8Array;
|
|
12
|
+
readonly overlap: number;
|
|
13
|
+
searchFrom: number;
|
|
14
|
+
constructor(pattern: Uint8Array);
|
|
15
|
+
/** Find the next match index starting at the current `searchFrom`. */
|
|
16
|
+
find(target: PatternSearchTarget): number;
|
|
17
|
+
/** Update `searchFrom` after consuming `consumed` bytes from the front. */
|
|
18
|
+
onConsume(consumed: number): void;
|
|
19
|
+
/** Update `searchFrom` after a no-match scan on a buffer of length `bufferLength`. */
|
|
20
|
+
onNoMatch(bufferLength: number): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stateful helper for incremental pattern scanning in growing buffers.
|
|
3
|
+
*
|
|
4
|
+
* The scanner tracks a `searchFrom` cursor and an `overlap` region so callers
|
|
5
|
+
* can avoid rescanning bytes that cannot start a match.
|
|
6
|
+
*/
|
|
7
|
+
export class PatternScanner {
|
|
8
|
+
constructor(pattern) {
|
|
9
|
+
this.searchFrom = 0;
|
|
10
|
+
this.pattern = pattern;
|
|
11
|
+
this.overlap = Math.max(0, pattern.length - 1);
|
|
12
|
+
}
|
|
13
|
+
/** Find the next match index starting at the current `searchFrom`. */
|
|
14
|
+
find(target) {
|
|
15
|
+
return target.indexOfPattern(this.pattern, this.searchFrom);
|
|
16
|
+
}
|
|
17
|
+
/** Update `searchFrom` after consuming `consumed` bytes from the front. */
|
|
18
|
+
onConsume(consumed) {
|
|
19
|
+
if (consumed > 0) {
|
|
20
|
+
this.searchFrom = Math.max(0, this.searchFrom - consumed);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Update `searchFrom` after a no-match scan on a buffer of length `bufferLength`. */
|
|
24
|
+
onNoMatch(bufferLength) {
|
|
25
|
+
this.searchFrom = Math.max(this.searchFrom, Math.max(0, bufferLength - this.overlap));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,4 +1,65 @@
|
|
|
1
|
-
|
|
1
|
+
const EXTENDED_TIMESTAMP_ID = 0x5455;
|
|
2
|
+
function clampUint32(value) {
|
|
3
|
+
if (!Number.isFinite(value)) {
|
|
4
|
+
return 0;
|
|
5
|
+
}
|
|
6
|
+
if (value <= 0) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
// 0xFFFFFFFF fits JS safe integer.
|
|
10
|
+
if (value >= 0xffffffff) {
|
|
11
|
+
return 0xffffffff;
|
|
12
|
+
}
|
|
13
|
+
return value >>> 0;
|
|
14
|
+
}
|
|
15
|
+
function unixSecondsFromDate(date) {
|
|
16
|
+
return clampUint32(Math.floor(date.getTime() / 1000));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse Info-ZIP "Extended Timestamp" extra field (0x5455) and return mtime.
|
|
20
|
+
* Returns Unix seconds (UTC) if present.
|
|
21
|
+
*/
|
|
22
|
+
function parseExtendedTimestampMtimeUnixSeconds(extraField) {
|
|
23
|
+
const view = new DataView(extraField.buffer, extraField.byteOffset, extraField.byteLength);
|
|
24
|
+
let offset = 0;
|
|
25
|
+
while (offset + 4 <= extraField.length) {
|
|
26
|
+
const headerId = view.getUint16(offset, true);
|
|
27
|
+
const dataSize = view.getUint16(offset + 2, true);
|
|
28
|
+
const dataStart = offset + 4;
|
|
29
|
+
const dataEnd = dataStart + dataSize;
|
|
30
|
+
if (dataEnd > extraField.length) {
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
if (headerId === EXTENDED_TIMESTAMP_ID && dataSize >= 1) {
|
|
34
|
+
const flags = extraField[dataStart];
|
|
35
|
+
if ((flags & 0x01) !== 0 && dataSize >= 5) {
|
|
36
|
+
// mtime is 4 bytes right after flags.
|
|
37
|
+
return view.getUint32(dataStart + 1, true) >>> 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
offset = dataEnd;
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build Info-ZIP "Extended Timestamp" extra field (0x5455).
|
|
46
|
+
* We write only mtime (UTC, Unix seconds) to minimize size.
|
|
47
|
+
*/
|
|
48
|
+
function buildExtendedTimestampExtraFieldFromUnixSeconds(unixSeconds) {
|
|
49
|
+
const ts = clampUint32(unixSeconds);
|
|
50
|
+
// flags(1) + mtime(4)
|
|
51
|
+
const payloadSize = 5;
|
|
52
|
+
const out = new Uint8Array(4 + payloadSize);
|
|
53
|
+
const view = new DataView(out.buffer);
|
|
54
|
+
view.setUint16(0, EXTENDED_TIMESTAMP_ID, true);
|
|
55
|
+
view.setUint16(2, payloadSize, true);
|
|
56
|
+
out[4] = 0x01; // mtime present
|
|
57
|
+
view.setUint32(5, ts, true);
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
function buildExtendedTimestampExtraFieldFromDate(date) {
|
|
61
|
+
return buildExtendedTimestampExtraFieldFromUnixSeconds(unixSecondsFromDate(date));
|
|
62
|
+
}
|
|
2
63
|
/**
|
|
3
64
|
* DOS date/time helpers for ZIP files.
|
|
4
65
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ZIP extra field parsing helpers.
|
|
3
3
|
*
|
|
4
|
-
* Kept standalone so both streaming parser (`
|
|
4
|
+
* Kept standalone so both streaming parser (`stream.base.ts`) and buffer parser
|
|
5
5
|
* (`zip-parser.ts`) can share ZIP64 + Info-ZIP timestamp handling.
|
|
6
6
|
*/
|
|
7
7
|
export interface ZipVars {
|
|
@@ -1,10 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ZIP extra field parsing helpers.
|
|
3
3
|
*
|
|
4
|
-
* Kept standalone so both streaming parser (`
|
|
4
|
+
* Kept standalone so both streaming parser (`stream.base.ts`) and buffer parser
|
|
5
5
|
* (`zip-parser.ts`) can share ZIP64 + Info-ZIP timestamp handling.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
const EXTENDED_TIMESTAMP_ID = 0x5455;
|
|
8
|
+
function parseExtendedTimestampMtimeUnixSeconds(extraField) {
|
|
9
|
+
const view = new DataView(extraField.buffer, extraField.byteOffset, extraField.byteLength);
|
|
10
|
+
let offset = 0;
|
|
11
|
+
while (offset + 4 <= extraField.length) {
|
|
12
|
+
const headerId = view.getUint16(offset, true);
|
|
13
|
+
const dataSize = view.getUint16(offset + 2, true);
|
|
14
|
+
const dataStart = offset + 4;
|
|
15
|
+
const dataEnd = dataStart + dataSize;
|
|
16
|
+
if (dataEnd > extraField.length) {
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
if (headerId === EXTENDED_TIMESTAMP_ID && dataSize >= 1) {
|
|
20
|
+
const flags = extraField[dataStart];
|
|
21
|
+
if ((flags & 0x01) !== 0 && dataSize >= 5) {
|
|
22
|
+
return view.getUint32(dataStart + 1, true) >>> 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
offset = dataEnd;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
8
29
|
function readUint64LE(view, offset) {
|
|
9
30
|
// Convert to Number via 2x Uint32 to avoid BigInt requirements.
|
|
10
31
|
const low = view.getUint32(offset, true);
|
|
@@ -43,18 +64,9 @@ export function parseZipExtraFields(extraField, vars) {
|
|
|
43
64
|
}
|
|
44
65
|
}
|
|
45
66
|
else if (signature === 0x5455) {
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
if ((flags & 0x01) !== 0 && partSize >= 5) {
|
|
50
|
-
extra.mtimeUnixSeconds = view.getUint32(dataStart + 1, true) >>> 0;
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
const unixSeconds = parseExtendedTimestampMtimeUnixSeconds(extraField.subarray(offset, dataEnd));
|
|
54
|
-
if (unixSeconds !== undefined) {
|
|
55
|
-
extra.mtimeUnixSeconds = unixSeconds;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
67
|
+
const unixSeconds = parseExtendedTimestampMtimeUnixSeconds(extraField.subarray(offset, dataEnd));
|
|
68
|
+
if (unixSeconds !== undefined) {
|
|
69
|
+
extra.mtimeUnixSeconds = unixSeconds;
|
|
58
70
|
}
|
|
59
71
|
}
|
|
60
72
|
offset = dataEnd;
|