@loaders.gl/zip 4.1.0-alpha.1 → 4.1.0-alpha.10

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 (68) hide show
  1. package/dist/dist.dev.js +313 -51
  2. package/dist/filesystems/zip-filesystem.d.ts.map +1 -1
  3. package/dist/filesystems/zip-filesystem.js.map +1 -1
  4. package/dist/hash-file-utility.d.ts +6 -0
  5. package/dist/hash-file-utility.d.ts.map +1 -1
  6. package/dist/hash-file-utility.js +22 -0
  7. package/dist/hash-file-utility.js.map +1 -1
  8. package/dist/index.cjs +290 -56
  9. package/dist/index.d.ts +3 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/tar/header.d.ts.map +1 -1
  14. package/dist/lib/tar/header.js.map +1 -1
  15. package/dist/lib/tar/tar.d.ts.map +1 -1
  16. package/dist/lib/tar/tar.js.map +1 -1
  17. package/dist/lib/tar/types.d.ts.map +1 -1
  18. package/dist/lib/tar/types.js.map +1 -1
  19. package/dist/lib/tar/utils.d.ts.map +1 -1
  20. package/dist/lib/tar/utils.js.map +1 -1
  21. package/dist/parse-zip/cd-file-header.d.ts +1 -1
  22. package/dist/parse-zip/cd-file-header.d.ts.map +1 -1
  23. package/dist/parse-zip/cd-file-header.js +4 -4
  24. package/dist/parse-zip/cd-file-header.js.map +1 -1
  25. package/dist/parse-zip/end-of-central-directory.d.ts +19 -0
  26. package/dist/parse-zip/end-of-central-directory.d.ts.map +1 -1
  27. package/dist/parse-zip/end-of-central-directory.js +41 -8
  28. package/dist/parse-zip/end-of-central-directory.js.map +1 -1
  29. package/dist/parse-zip/local-file-header.d.ts +16 -0
  30. package/dist/parse-zip/local-file-header.d.ts.map +1 -1
  31. package/dist/parse-zip/local-file-header.js +73 -1
  32. package/dist/parse-zip/local-file-header.js.map +1 -1
  33. package/dist/parse-zip/search-from-the-end.d.ts.map +1 -1
  34. package/dist/parse-zip/search-from-the-end.js.map +1 -1
  35. package/dist/parse-zip/zip-compozition.d.ts +8 -0
  36. package/dist/parse-zip/zip-compozition.d.ts.map +1 -0
  37. package/dist/parse-zip/zip-compozition.js +43 -0
  38. package/dist/parse-zip/zip-compozition.js.map +1 -0
  39. package/dist/parse-zip/zip64-info-generation.d.ts +5 -8
  40. package/dist/parse-zip/zip64-info-generation.d.ts.map +1 -1
  41. package/dist/parse-zip/zip64-info-generation.js +6 -3
  42. package/dist/parse-zip/zip64-info-generation.js.map +1 -1
  43. package/dist/tar-builder.d.ts.map +1 -1
  44. package/dist/tar-builder.js.map +1 -1
  45. package/dist/zip-loader.d.ts.map +1 -1
  46. package/dist/zip-loader.js +1 -1
  47. package/dist/zip-loader.js.map +1 -1
  48. package/dist/zip-writer.d.ts +2 -2
  49. package/dist/zip-writer.d.ts.map +1 -1
  50. package/dist/zip-writer.js +22 -7
  51. package/dist/zip-writer.js.map +1 -1
  52. package/package.json +7 -7
  53. package/src/filesystems/zip-filesystem.ts +2 -1
  54. package/src/hash-file-utility.ts +52 -2
  55. package/src/index.ts +6 -3
  56. package/src/lib/tar/header.ts +2 -1
  57. package/src/lib/tar/tar.ts +2 -1
  58. package/src/lib/tar/types.ts +2 -1
  59. package/src/lib/tar/utils.ts +2 -1
  60. package/src/parse-zip/cd-file-header.ts +8 -6
  61. package/src/parse-zip/end-of-central-directory.ts +99 -9
  62. package/src/parse-zip/local-file-header.ts +128 -2
  63. package/src/parse-zip/search-from-the-end.ts +2 -1
  64. package/src/parse-zip/zip-compozition.ts +113 -0
  65. package/src/parse-zip/zip64-info-generation.ts +20 -4
  66. package/src/tar-builder.ts +2 -1
  67. package/src/zip-loader.ts +2 -1
  68. package/src/zip-writer.ts +24 -10
@@ -1 +1 @@
1
- {"version":3,"file":"tar-builder.d.ts","sourceRoot":"","sources":["../src/tar-builder.ts"],"names":[],"mappings":"AAGA,OAAO,GAAG,MAAM,eAAe,CAAC;AAMhC,KAAK,iBAAiB,GAAG;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,qBAAa,UAAU;IACrB,MAAM,KAAK,UAAU;;;;;;;;;MASpB;IAED,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,MAAM,CAAK;gBAEN,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAIhD,kCAAkC;IAClC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAKvC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;CAGpC"}
1
+ {"version":3,"file":"tar-builder.d.ts","sourceRoot":"","sources":["../src/tar-builder.ts"],"names":[],"mappings":"AAIA,OAAO,GAAG,MAAM,eAAe,CAAC;AAMhC,KAAK,iBAAiB,GAAG;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,qBAAa,UAAU;IACrB,MAAM,KAAK,UAAU;;;;;;;;;MASpB;IAED,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,GAAG,CAAC;IACV,KAAK,EAAE,MAAM,CAAK;gBAEN,OAAO,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAIhD,kCAAkC;IAClC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW;IAKvC,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;CAGpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tar-builder.js","names":["Tar","TAR_BUILDER_OPTIONS","recordsPerBlock","TarBuilder","properties","id","name","extensions","mimeTypes","builder","options","constructor","tape","count","addFile","filename","buffer","append","Uint8Array","build","Response","save","arrayBuffer"],"sources":["../src/tar-builder.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport Tar from './lib/tar/tar';\n\nconst TAR_BUILDER_OPTIONS = {\n recordsPerBlock: 20\n};\n\ntype TarBuilderOptions = {\n recordsPerBlock?: number;\n};\n\n/**\n * Build a tar file by adding files\n */\nexport class TarBuilder {\n static get properties() {\n return {\n id: 'tar',\n name: 'TAR',\n extensions: ['tar'],\n mimeTypes: ['application/x-tar'],\n builder: TarBuilder,\n options: TAR_BUILDER_OPTIONS\n };\n }\n\n options: TarBuilderOptions;\n tape: Tar;\n count: number = 0;\n\n constructor(options?: Partial<TarBuilderOptions>) {\n this.options = {...TAR_BUILDER_OPTIONS, ...options};\n this.tape = new Tar(this.options.recordsPerBlock);\n }\n /** Adds a file to the archive. */\n addFile(filename: string, buffer: ArrayBuffer) {\n this.tape.append(filename, new Uint8Array(buffer));\n this.count++;\n }\n\n async build(): Promise<ArrayBuffer> {\n return new Response(this.tape.save()).arrayBuffer();\n }\n}\n"],"mappings":"OAGOA,GAAG;AAEV,MAAMC,mBAAmB,GAAG;EAC1BC,eAAe,EAAE;AACnB,CAAC;AASD,OAAO,MAAMC,UAAU,CAAC;EACtB,WAAWC,UAAUA,CAAA,EAAG;IACtB,OAAO;MACLC,EAAE,EAAE,KAAK;MACTC,IAAI,EAAE,KAAK;MACXC,UAAU,EAAE,CAAC,KAAK,CAAC;MACnBC,SAAS,EAAE,CAAC,mBAAmB,CAAC;MAChCC,OAAO,EAAEN,UAAU;MACnBO,OAAO,EAAET;IACX,CAAC;EACH;EAMAU,WAAWA,CAACD,OAAoC,EAAE;IAAA,KAJlDA,OAAO;IAAA,KACPE,IAAI;IAAA,KACJC,KAAK,GAAW,CAAC;IAGf,IAAI,CAACH,OAAO,GAAG;MAAC,GAAGT,mBAAmB;MAAE,GAAGS;IAAO,CAAC;IACnD,IAAI,CAACE,IAAI,GAAG,IAAIZ,GAAG,CAAC,IAAI,CAACU,OAAO,CAACR,eAAe,CAAC;EACnD;EAEAY,OAAOA,CAACC,QAAgB,EAAEC,MAAmB,EAAE;IAC7C,IAAI,CAACJ,IAAI,CAACK,MAAM,CAACF,QAAQ,EAAE,IAAIG,UAAU,CAACF,MAAM,CAAC,CAAC;IAClD,IAAI,CAACH,KAAK,EAAE;EACd;EAEA,MAAMM,KAAKA,CAAA,EAAyB;IAClC,OAAO,IAAIC,QAAQ,CAAC,IAAI,CAACR,IAAI,CAACS,IAAI,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;EACrD;AACF"}
1
+ {"version":3,"file":"tar-builder.js","names":["Tar","TAR_BUILDER_OPTIONS","recordsPerBlock","TarBuilder","properties","id","name","extensions","mimeTypes","builder","options","constructor","tape","count","addFile","filename","buffer","append","Uint8Array","build","Response","save","arrayBuffer"],"sources":["../src/tar-builder.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport Tar from './lib/tar/tar';\n\nconst TAR_BUILDER_OPTIONS = {\n recordsPerBlock: 20\n};\n\ntype TarBuilderOptions = {\n recordsPerBlock?: number;\n};\n\n/**\n * Build a tar file by adding files\n */\nexport class TarBuilder {\n static get properties() {\n return {\n id: 'tar',\n name: 'TAR',\n extensions: ['tar'],\n mimeTypes: ['application/x-tar'],\n builder: TarBuilder,\n options: TAR_BUILDER_OPTIONS\n };\n }\n\n options: TarBuilderOptions;\n tape: Tar;\n count: number = 0;\n\n constructor(options?: Partial<TarBuilderOptions>) {\n this.options = {...TAR_BUILDER_OPTIONS, ...options};\n this.tape = new Tar(this.options.recordsPerBlock);\n }\n /** Adds a file to the archive. */\n addFile(filename: string, buffer: ArrayBuffer) {\n this.tape.append(filename, new Uint8Array(buffer));\n this.count++;\n }\n\n async build(): Promise<ArrayBuffer> {\n return new Response(this.tape.save()).arrayBuffer();\n }\n}\n"],"mappings":"OAIOA,GAAG;AAEV,MAAMC,mBAAmB,GAAG;EAC1BC,eAAe,EAAE;AACnB,CAAC;AASD,OAAO,MAAMC,UAAU,CAAC;EACtB,WAAWC,UAAUA,CAAA,EAAG;IACtB,OAAO;MACLC,EAAE,EAAE,KAAK;MACTC,IAAI,EAAE,KAAK;MACXC,UAAU,EAAE,CAAC,KAAK,CAAC;MACnBC,SAAS,EAAE,CAAC,mBAAmB,CAAC;MAChCC,OAAO,EAAEN,UAAU;MACnBO,OAAO,EAAET;IACX,CAAC;EACH;EAMAU,WAAWA,CAACD,OAAoC,EAAE;IAAA,KAJlDA,OAAO;IAAA,KACPE,IAAI;IAAA,KACJC,KAAK,GAAW,CAAC;IAGf,IAAI,CAACH,OAAO,GAAG;MAAC,GAAGT,mBAAmB;MAAE,GAAGS;IAAO,CAAC;IACnD,IAAI,CAACE,IAAI,GAAG,IAAIZ,GAAG,CAAC,IAAI,CAACU,OAAO,CAACR,eAAe,CAAC;EACnD;EAEAY,OAAOA,CAACC,QAAgB,EAAEC,MAAmB,EAAE;IAC7C,IAAI,CAACJ,IAAI,CAACK,MAAM,CAACF,QAAQ,EAAE,IAAIG,UAAU,CAACF,MAAM,CAAC,CAAC;IAClD,IAAI,CAACH,KAAK,EAAE;EACd;EAEA,MAAMM,KAAKA,CAAA,EAAyB;IAClC,OAAO,IAAIC,QAAQ,CAAC,IAAI,CAACR,IAAI,CAACS,IAAI,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;EACrD;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"zip-loader.d.ts","sourceRoot":"","sources":["../src/zip-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,gBAAgB,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAO9E,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE3C,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAWrE,CAAC"}
1
+ {"version":3,"file":"zip-loader.d.ts","sourceRoot":"","sources":["../src/zip-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,gBAAgB,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAO9E,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAE3C,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAWrE,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import JSZip from 'jszip';
2
- const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
2
+ const VERSION = typeof "4.1.0-alpha.10" !== 'undefined' ? "4.1.0-alpha.10" : 'latest';
3
3
  export const ZipLoader = {
4
4
  id: 'zip',
5
5
  module: 'zip',
@@ -1 +1 @@
1
- {"version":3,"file":"zip-loader.js","names":["JSZip","VERSION","__VERSION__","ZipLoader","id","module","name","version","extensions","mimeTypes","category","tests","options","parse","parseZipAsync","data","arguments","length","undefined","promises","fileMap","jsZip","zip","loadAsync","forEach","relativePath","zipEntry","subFilename","promise","loadZipEntry","then","arrayBufferOrError","push","Promise","all","error","log","arrayBuffer","file","async","dataType"],"sources":["../src/zip-loader.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';\nimport JSZip from 'jszip';\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\n\ntype FileMap = Record<string, ArrayBuffer>;\n\nexport const ZipLoader: LoaderWithParser<FileMap, never, LoaderOptions> = {\n id: 'zip',\n module: 'zip',\n name: 'Zip Archive',\n version: VERSION,\n extensions: ['zip'],\n mimeTypes: ['application/zip'],\n category: 'archive',\n tests: ['PK'],\n options: {},\n parse: parseZipAsync\n};\n\n// TODO - Could return a map of promises, perhaps as an option...\nasync function parseZipAsync(data: any, options = {}): Promise<FileMap> {\n const promises: Promise<any>[] = [];\n const fileMap: Record<string, ArrayBuffer> = {};\n\n try {\n const jsZip = new JSZip();\n\n const zip = await jsZip.loadAsync(data, options);\n\n // start to load each file in this zip\n zip.forEach((relativePath, zipEntry) => {\n const subFilename = zipEntry.name;\n\n const promise = loadZipEntry(jsZip, subFilename, options).then((arrayBufferOrError) => {\n fileMap[relativePath] = arrayBufferOrError;\n });\n\n // Ensure Promise.all doesn't ignore rejected promises.\n promises.push(promise);\n });\n\n await Promise.all(promises);\n return fileMap;\n } catch (error) {\n // @ts-ignore\n options.log.error(`Unable to read zip archive: ${error}`);\n throw error;\n }\n}\n\nasync function loadZipEntry(jsZip: any, subFilename: string, options: any = {}) {\n // jszip supports both arraybuffer and text, the main loaders.gl types\n // https://stuk.github.io/jszip/documentation/api_zipobject/async.html\n try {\n const arrayBuffer = await jsZip.file(subFilename).async(options.dataType || 'arraybuffer');\n return arrayBuffer;\n } catch (error) {\n options.log.error(`Unable to read ${subFilename} from zip archive: ${error}`);\n // Store error in place of data in map\n return error;\n }\n}\n"],"mappings":"AAIA,OAAOA,KAAK,MAAM,OAAO;AAIzB,MAAMC,OAAO,GAAG,OAAOC,WAAW,KAAK,WAAW,GAAGA,WAAW,GAAG,QAAQ;AAI3E,OAAO,MAAMC,SAA0D,GAAG;EACxEC,EAAE,EAAE,KAAK;EACTC,MAAM,EAAE,KAAK;EACbC,IAAI,EAAE,aAAa;EACnBC,OAAO,EAAEN,OAAO;EAChBO,UAAU,EAAE,CAAC,KAAK,CAAC;EACnBC,SAAS,EAAE,CAAC,iBAAiB,CAAC;EAC9BC,QAAQ,EAAE,SAAS;EACnBC,KAAK,EAAE,CAAC,IAAI,CAAC;EACbC,OAAO,EAAE,CAAC,CAAC;EACXC,KAAK,EAAEC;AACT,CAAC;AAGD,eAAeA,aAAaA,CAACC,IAAS,EAAkC;EAAA,IAAhCH,OAAO,GAAAI,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAClD,MAAMG,QAAwB,GAAG,EAAE;EACnC,MAAMC,OAAoC,GAAG,CAAC,CAAC;EAE/C,IAAI;IACF,MAAMC,KAAK,GAAG,IAAIrB,KAAK,CAAC,CAAC;IAEzB,MAAMsB,GAAG,GAAG,MAAMD,KAAK,CAACE,SAAS,CAACR,IAAI,EAAEH,OAAO,CAAC;IAGhDU,GAAG,CAACE,OAAO,CAAC,CAACC,YAAY,EAAEC,QAAQ,KAAK;MACtC,MAAMC,WAAW,GAAGD,QAAQ,CAACpB,IAAI;MAEjC,MAAMsB,OAAO,GAAGC,YAAY,CAACR,KAAK,EAAEM,WAAW,EAAEf,OAAO,CAAC,CAACkB,IAAI,CAAEC,kBAAkB,IAAK;QACrFX,OAAO,CAACK,YAAY,CAAC,GAAGM,kBAAkB;MAC5C,CAAC,CAAC;MAGFZ,QAAQ,CAACa,IAAI,CAACJ,OAAO,CAAC;IACxB,CAAC,CAAC;IAEF,MAAMK,OAAO,CAACC,GAAG,CAACf,QAAQ,CAAC;IAC3B,OAAOC,OAAO;EAChB,CAAC,CAAC,OAAOe,KAAK,EAAE;IAEdvB,OAAO,CAACwB,GAAG,CAACD,KAAK,CAAE,+BAA8BA,KAAM,EAAC,CAAC;IACzD,MAAMA,KAAK;EACb;AACF;AAEA,eAAeN,YAAYA,CAACR,KAAU,EAAEM,WAAmB,EAAqB;EAAA,IAAnBf,OAAY,GAAAI,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAG5E,IAAI;IACF,MAAMqB,WAAW,GAAG,MAAMhB,KAAK,CAACiB,IAAI,CAACX,WAAW,CAAC,CAACY,KAAK,CAAC3B,OAAO,CAAC4B,QAAQ,IAAI,aAAa,CAAC;IAC1F,OAAOH,WAAW;EACpB,CAAC,CAAC,OAAOF,KAAK,EAAE;IACdvB,OAAO,CAACwB,GAAG,CAACD,KAAK,CAAE,kBAAiBR,WAAY,sBAAqBQ,KAAM,EAAC,CAAC;IAE7E,OAAOA,KAAK;EACd;AACF"}
1
+ {"version":3,"file":"zip-loader.js","names":["JSZip","VERSION","ZipLoader","id","module","name","version","extensions","mimeTypes","category","tests","options","parse","parseZipAsync","data","arguments","length","undefined","promises","fileMap","jsZip","zip","loadAsync","forEach","relativePath","zipEntry","subFilename","promise","loadZipEntry","then","arrayBufferOrError","push","Promise","all","error","log","arrayBuffer","file","async","dataType"],"sources":["../src/zip-loader.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';\nimport JSZip from 'jszip';\n\n// __VERSION__ is injected by babel-plugin-version-inline\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\n\ntype FileMap = Record<string, ArrayBuffer>;\n\nexport const ZipLoader: LoaderWithParser<FileMap, never, LoaderOptions> = {\n id: 'zip',\n module: 'zip',\n name: 'Zip Archive',\n version: VERSION,\n extensions: ['zip'],\n mimeTypes: ['application/zip'],\n category: 'archive',\n tests: ['PK'],\n options: {},\n parse: parseZipAsync\n};\n\n// TODO - Could return a map of promises, perhaps as an option...\nasync function parseZipAsync(data: any, options = {}): Promise<FileMap> {\n const promises: Promise<any>[] = [];\n const fileMap: Record<string, ArrayBuffer> = {};\n\n try {\n const jsZip = new JSZip();\n\n const zip = await jsZip.loadAsync(data, options);\n\n // start to load each file in this zip\n zip.forEach((relativePath, zipEntry) => {\n const subFilename = zipEntry.name;\n\n const promise = loadZipEntry(jsZip, subFilename, options).then((arrayBufferOrError) => {\n fileMap[relativePath] = arrayBufferOrError;\n });\n\n // Ensure Promise.all doesn't ignore rejected promises.\n promises.push(promise);\n });\n\n await Promise.all(promises);\n return fileMap;\n } catch (error) {\n // @ts-ignore\n options.log.error(`Unable to read zip archive: ${error}`);\n throw error;\n }\n}\n\nasync function loadZipEntry(jsZip: any, subFilename: string, options: any = {}) {\n // jszip supports both arraybuffer and text, the main loaders.gl types\n // https://stuk.github.io/jszip/documentation/api_zipobject/async.html\n try {\n const arrayBuffer = await jsZip.file(subFilename).async(options.dataType || 'arraybuffer');\n return arrayBuffer;\n } catch (error) {\n options.log.error(`Unable to read ${subFilename} from zip archive: ${error}`);\n // Store error in place of data in map\n return error;\n }\n}\n"],"mappings":"AAKA,OAAOA,KAAK,MAAM,OAAO;AAIzB,MAAMC,OAAO,GAAG,uBAAkB,KAAK,WAAW,sBAAiB,QAAQ;AAI3E,OAAO,MAAMC,SAA0D,GAAG;EACxEC,EAAE,EAAE,KAAK;EACTC,MAAM,EAAE,KAAK;EACbC,IAAI,EAAE,aAAa;EACnBC,OAAO,EAAEL,OAAO;EAChBM,UAAU,EAAE,CAAC,KAAK,CAAC;EACnBC,SAAS,EAAE,CAAC,iBAAiB,CAAC;EAC9BC,QAAQ,EAAE,SAAS;EACnBC,KAAK,EAAE,CAAC,IAAI,CAAC;EACbC,OAAO,EAAE,CAAC,CAAC;EACXC,KAAK,EAAEC;AACT,CAAC;AAGD,eAAeA,aAAaA,CAACC,IAAS,EAAkC;EAAA,IAAhCH,OAAO,GAAAI,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAClD,MAAMG,QAAwB,GAAG,EAAE;EACnC,MAAMC,OAAoC,GAAG,CAAC,CAAC;EAE/C,IAAI;IACF,MAAMC,KAAK,GAAG,IAAIpB,KAAK,CAAC,CAAC;IAEzB,MAAMqB,GAAG,GAAG,MAAMD,KAAK,CAACE,SAAS,CAACR,IAAI,EAAEH,OAAO,CAAC;IAGhDU,GAAG,CAACE,OAAO,CAAC,CAACC,YAAY,EAAEC,QAAQ,KAAK;MACtC,MAAMC,WAAW,GAAGD,QAAQ,CAACpB,IAAI;MAEjC,MAAMsB,OAAO,GAAGC,YAAY,CAACR,KAAK,EAAEM,WAAW,EAAEf,OAAO,CAAC,CAACkB,IAAI,CAAEC,kBAAkB,IAAK;QACrFX,OAAO,CAACK,YAAY,CAAC,GAAGM,kBAAkB;MAC5C,CAAC,CAAC;MAGFZ,QAAQ,CAACa,IAAI,CAACJ,OAAO,CAAC;IACxB,CAAC,CAAC;IAEF,MAAMK,OAAO,CAACC,GAAG,CAACf,QAAQ,CAAC;IAC3B,OAAOC,OAAO;EAChB,CAAC,CAAC,OAAOe,KAAK,EAAE;IAEdvB,OAAO,CAACwB,GAAG,CAACD,KAAK,CAAE,+BAA8BA,KAAM,EAAC,CAAC;IACzD,MAAMA,KAAK;EACb;AACF;AAEA,eAAeN,YAAYA,CAACR,KAAU,EAAEM,WAAmB,EAAqB;EAAA,IAAnBf,OAAY,GAAAI,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAG5E,IAAI;IACF,MAAMqB,WAAW,GAAG,MAAMhB,KAAK,CAACiB,IAAI,CAACX,WAAW,CAAC,CAACY,KAAK,CAAC3B,OAAO,CAAC4B,QAAQ,IAAI,aAAa,CAAC;IAC1F,OAAOH,WAAW;EACpB,CAAC,CAAC,OAAOF,KAAK,EAAE;IACdvB,OAAO,CAACwB,GAAG,CAACD,KAAK,CAAE,kBAAiBR,WAAY,sBAAqBQ,KAAM,EAAC,CAAC;IAE7E,OAAOA,KAAK;EACd;AACF"}
@@ -1,4 +1,4 @@
1
- import type { Writer, WriterOptions } from '@loaders.gl/loader-utils';
1
+ import type { WriterWithEncoder, WriterOptions } from '@loaders.gl/loader-utils';
2
2
  import { JSZipGeneratorOptions } from 'jszip';
3
3
  export type ZipWriterOptions = WriterOptions & {
4
4
  zip?: {
@@ -12,5 +12,5 @@ export type ZipWriterOptions = WriterOptions & {
12
12
  /**
13
13
  * Zip exporter
14
14
  */
15
- export declare const ZipWriter: Writer<FileReaderEventMap, never, ZipWriterOptions>;
15
+ export declare const ZipWriter: WriterWithEncoder<Record<string, ArrayBuffer>, never, ZipWriterOptions>;
16
16
  //# sourceMappingURL=zip-writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zip-writer.d.ts","sourceRoot":"","sources":["../src/zip-writer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AACpE,OAAc,EAAC,qBAAqB,EAAC,MAAM,OAAO,CAAC;AAEnD,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE;YAAC,OAAO,EAAE,MAAM,CAAA;SAAC,KAAK,IAAI,CAAC;KAClD,CAAC;IACF,mCAAmC;IACnC,KAAK,CAAC,EAAE,qBAAqB,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,kBAAkB,EAAE,KAAK,EAAE,gBAAgB,CAOzE,CAAC"}
1
+ {"version":3,"file":"zip-writer.d.ts","sourceRoot":"","sources":["../src/zip-writer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,iBAAiB,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAC/E,OAAc,EAAC,qBAAqB,EAAC,MAAM,OAAO,CAAC;AAKnD,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC7C,GAAG,CAAC,EAAE;QACJ,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE;YAAC,OAAO,EAAE,MAAM,CAAA;SAAC,KAAK,IAAI,CAAC;KAClD,CAAC;IACF,mCAAmC;IACnC,KAAK,CAAC,EAAE,qBAAqB,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAe7F,CAAC"}
@@ -1,29 +1,44 @@
1
1
  import JSZip from 'jszip';
2
+ const VERSION = typeof "4.1.0-alpha.10" !== 'undefined' ? "4.1.0-alpha.10" : 'latest';
2
3
  export const ZipWriter = {
3
4
  name: 'Zip Archive',
5
+ id: 'zip',
6
+ module: 'zip',
7
+ version: VERSION,
4
8
  extensions: ['zip'],
5
9
  category: 'archive',
6
10
  mimeTypes: ['application/zip'],
11
+ options: {
12
+ zip: {
13
+ onUpdate: () => {}
14
+ },
15
+ jszip: {}
16
+ },
7
17
  encode: encodeZipAsync
8
18
  };
9
19
  async function encodeZipAsync(fileMap) {
20
+ var _ZipWriter$options;
10
21
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
11
22
  const jsZip = new JSZip();
12
23
  for (const subFileName in fileMap) {
13
24
  const subFileData = fileMap[subFileName];
14
25
  jsZip.file(subFileName, subFileData, (options === null || options === void 0 ? void 0 : options.jszip) || {});
15
26
  }
27
+ const zipOptions = {
28
+ ...ZipWriter.options.zip,
29
+ ...(options === null || options === void 0 ? void 0 : options.zip)
30
+ };
16
31
  const jszipOptions = {
17
- ...(options === null || options === void 0 ? void 0 : options.jszip),
18
- type: 'arraybuffer'
32
+ ...((_ZipWriter$options = ZipWriter.options) === null || _ZipWriter$options === void 0 ? void 0 : _ZipWriter$options.jszip),
33
+ ...options.jszip
19
34
  };
20
- const {
21
- onUpdate = () => {}
22
- } = options;
23
35
  try {
24
- return await jsZip.generateAsync(jszipOptions, onUpdate);
36
+ return await jsZip.generateAsync({
37
+ ...jszipOptions,
38
+ type: 'arraybuffer'
39
+ }, zipOptions.onUpdate);
25
40
  } catch (error) {
26
- options.log.error(`Unable to write zip archive: ${error}`);
41
+ options.log.error(`Unable to encode zip archive: ${error}`);
27
42
  throw error;
28
43
  }
29
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"zip-writer.js","names":["JSZip","ZipWriter","name","extensions","category","mimeTypes","encode","encodeZipAsync","fileMap","options","arguments","length","undefined","jsZip","subFileName","subFileData","file","jszip","jszipOptions","type","onUpdate","generateAsync","error","log"],"sources":["../src/zip-writer.ts"],"sourcesContent":["// loaders.gl, MIT license\n// Copyright (c) vis.gl contributors\n\nimport type {Writer, WriterOptions} from '@loaders.gl/loader-utils';\nimport JSZip, {JSZipGeneratorOptions} from 'jszip';\n\nexport type ZipWriterOptions = WriterOptions & {\n zip?: {\n onUpdate?: (metadata: {percent: number}) => void;\n };\n /** Passthrough options to jszip */\n jszip?: JSZipGeneratorOptions;\n};\n\n/**\n * Zip exporter\n */\nexport const ZipWriter: Writer<FileReaderEventMap, never, ZipWriterOptions> = {\n name: 'Zip Archive',\n extensions: ['zip'],\n category: 'archive',\n mimeTypes: ['application/zip'],\n // @ts-ignore\n encode: encodeZipAsync\n};\n\nasync function encodeZipAsync(\n fileMap: Record<string, ArrayBuffer>,\n options: ZipWriterOptions = {}\n) {\n const jsZip = new JSZip();\n // add files to the zip\n for (const subFileName in fileMap) {\n const subFileData = fileMap[subFileName];\n\n // jszip supports both arraybuffer and string data (the main loaders.gl types)\n // https://stuk.github.io/jszip/documentation/api_zipobject/async.html\n jsZip.file(subFileName, subFileData, options?.jszip || {});\n }\n\n // always generate the full zip as an arraybuffer\n const jszipOptions: JSZipGeneratorOptions = {...options?.jszip, type: 'arraybuffer'};\n const {onUpdate = () => {}} = options;\n\n try {\n return await jsZip.generateAsync(jszipOptions, onUpdate);\n } catch (error) {\n options.log.error(`Unable to write zip archive: ${error}`);\n throw error;\n }\n}\n"],"mappings":"AAIA,OAAOA,KAAK,MAA+B,OAAO;AAalD,OAAO,MAAMC,SAA8D,GAAG;EAC5EC,IAAI,EAAE,aAAa;EACnBC,UAAU,EAAE,CAAC,KAAK,CAAC;EACnBC,QAAQ,EAAE,SAAS;EACnBC,SAAS,EAAE,CAAC,iBAAiB,CAAC;EAE9BC,MAAM,EAAEC;AACV,CAAC;AAED,eAAeA,cAAcA,CAC3BC,OAAoC,EAEpC;EAAA,IADAC,OAAyB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAE9B,MAAMG,KAAK,GAAG,IAAIb,KAAK,CAAC,CAAC;EAEzB,KAAK,MAAMc,WAAW,IAAIN,OAAO,EAAE;IACjC,MAAMO,WAAW,GAAGP,OAAO,CAACM,WAAW,CAAC;IAIxCD,KAAK,CAACG,IAAI,CAACF,WAAW,EAAEC,WAAW,EAAE,CAAAN,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEQ,KAAK,KAAI,CAAC,CAAC,CAAC;EAC5D;EAGA,MAAMC,YAAmC,GAAG;IAAC,IAAGT,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEQ,KAAK;IAAEE,IAAI,EAAE;EAAa,CAAC;EACpF,MAAM;IAACC,QAAQ,GAAGA,CAAA,KAAM,CAAC;EAAC,CAAC,GAAGX,OAAO;EAErC,IAAI;IACF,OAAO,MAAMI,KAAK,CAACQ,aAAa,CAACH,YAAY,EAAEE,QAAQ,CAAC;EAC1D,CAAC,CAAC,OAAOE,KAAK,EAAE;IACdb,OAAO,CAACc,GAAG,CAACD,KAAK,CAAE,gCAA+BA,KAAM,EAAC,CAAC;IAC1D,MAAMA,KAAK;EACb;AACF"}
1
+ {"version":3,"file":"zip-writer.js","names":["JSZip","VERSION","ZipWriter","name","id","module","version","extensions","category","mimeTypes","options","zip","onUpdate","jszip","encode","encodeZipAsync","fileMap","_ZipWriter$options","arguments","length","undefined","jsZip","subFileName","subFileData","file","zipOptions","jszipOptions","generateAsync","type","error","log"],"sources":["../src/zip-writer.ts"],"sourcesContent":["// loaders.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {WriterWithEncoder, WriterOptions} from '@loaders.gl/loader-utils';\nimport JSZip, {JSZipGeneratorOptions} from 'jszip';\n\n// @ts-ignore TS2304: Cannot find name '__VERSION__'.\nconst VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';\n\nexport type ZipWriterOptions = WriterOptions & {\n zip?: {\n onUpdate?: (metadata: {percent: number}) => void;\n };\n /** Passthrough options to jszip */\n jszip?: JSZipGeneratorOptions;\n};\n\n/**\n * Zip exporter\n */\nexport const ZipWriter: WriterWithEncoder<Record<string, ArrayBuffer>, never, ZipWriterOptions> = {\n name: 'Zip Archive',\n id: 'zip',\n module: 'zip',\n version: VERSION,\n extensions: ['zip'],\n category: 'archive',\n mimeTypes: ['application/zip'],\n options: {\n zip: {\n onUpdate: () => {}\n },\n jszip: {}\n },\n encode: encodeZipAsync\n};\n\nasync function encodeZipAsync(\n fileMap: Record<string, ArrayBuffer>,\n options: ZipWriterOptions = {}\n): Promise<ArrayBuffer> {\n const jsZip = new JSZip();\n // add files to the zip\n for (const subFileName in fileMap) {\n const subFileData = fileMap[subFileName];\n\n // jszip supports both arraybuffer and string data (the main loaders.gl types)\n // https://stuk.github.io/jszip/documentation/api_zipobject/async.html\n jsZip.file(subFileName, subFileData, options?.jszip || {});\n }\n\n const zipOptions = {...ZipWriter.options.zip, ...options?.zip};\n const jszipOptions: JSZipGeneratorOptions = {...ZipWriter.options?.jszip, ...options.jszip};\n\n try {\n return await jsZip.generateAsync(\n {...jszipOptions, type: 'arraybuffer'}, // generate an arraybuffer\n zipOptions.onUpdate\n );\n } catch (error) {\n options.log.error(`Unable to encode zip archive: ${error}`);\n throw error;\n }\n}\n"],"mappings":"AAKA,OAAOA,KAAK,MAA+B,OAAO;AAGlD,MAAMC,OAAO,GAAG,uBAAkB,KAAK,WAAW,sBAAiB,QAAQ;AAa3E,OAAO,MAAMC,SAAkF,GAAG;EAChGC,IAAI,EAAE,aAAa;EACnBC,EAAE,EAAE,KAAK;EACTC,MAAM,EAAE,KAAK;EACbC,OAAO,EAAEL,OAAO;EAChBM,UAAU,EAAE,CAAC,KAAK,CAAC;EACnBC,QAAQ,EAAE,SAAS;EACnBC,SAAS,EAAE,CAAC,iBAAiB,CAAC;EAC9BC,OAAO,EAAE;IACPC,GAAG,EAAE;MACHC,QAAQ,EAAEA,CAAA,KAAM,CAAC;IACnB,CAAC;IACDC,KAAK,EAAE,CAAC;EACV,CAAC;EACDC,MAAM,EAAEC;AACV,CAAC;AAED,eAAeA,cAAcA,CAC3BC,OAAoC,EAEd;EAAA,IAAAC,kBAAA;EAAA,IADtBP,OAAyB,GAAAQ,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,CAAC,CAAC;EAE9B,MAAMG,KAAK,GAAG,IAAIrB,KAAK,CAAC,CAAC;EAEzB,KAAK,MAAMsB,WAAW,IAAIN,OAAO,EAAE;IACjC,MAAMO,WAAW,GAAGP,OAAO,CAACM,WAAW,CAAC;IAIxCD,KAAK,CAACG,IAAI,CAACF,WAAW,EAAEC,WAAW,EAAE,CAAAb,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,KAAK,KAAI,CAAC,CAAC,CAAC;EAC5D;EAEA,MAAMY,UAAU,GAAG;IAAC,GAAGvB,SAAS,CAACQ,OAAO,CAACC,GAAG;IAAE,IAAGD,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEC,GAAG;EAAA,CAAC;EAC9D,MAAMe,YAAmC,GAAG;IAAC,KAAAT,kBAAA,GAAGf,SAAS,CAACQ,OAAO,cAAAO,kBAAA,uBAAjBA,kBAAA,CAAmBJ,KAAK;IAAE,GAAGH,OAAO,CAACG;EAAK,CAAC;EAE3F,IAAI;IACF,OAAO,MAAMQ,KAAK,CAACM,aAAa,CAC9B;MAAC,GAAGD,YAAY;MAAEE,IAAI,EAAE;IAAa,CAAC,EACtCH,UAAU,CAACb,QACb,CAAC;EACH,CAAC,CAAC,OAAOiB,KAAK,EAAE;IACdnB,OAAO,CAACoB,GAAG,CAACD,KAAK,CAAE,iCAAgCA,KAAM,EAAC,CAAC;IAC3D,MAAMA,KAAK;EACb;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/zip",
3
- "version": "4.1.0-alpha.1",
3
+ "version": "4.1.0-alpha.10",
4
4
  "description": "Zip Archive Loader",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,9 +22,9 @@
22
22
  "module": "dist/index.js",
23
23
  "exports": {
24
24
  ".": {
25
+ "types": "./dist/index.d.ts",
25
26
  "import": "./dist/index.js",
26
- "require": "./dist/index.cjs",
27
- "types": "./dist/index.d.ts"
27
+ "require": "./dist/index.cjs"
28
28
  }
29
29
  },
30
30
  "sideEffects": false,
@@ -38,11 +38,11 @@
38
38
  "build-bundle": "ocular-bundle ./src/index.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@loaders.gl/compression": "4.1.0-alpha.1",
42
- "@loaders.gl/crypto": "4.1.0-alpha.1",
43
- "@loaders.gl/loader-utils": "4.1.0-alpha.1",
41
+ "@loaders.gl/compression": "4.1.0-alpha.10",
42
+ "@loaders.gl/crypto": "4.1.0-alpha.10",
43
+ "@loaders.gl/loader-utils": "4.1.0-alpha.10",
44
44
  "jszip": "^3.1.5",
45
45
  "md5": "^2.3.0"
46
46
  },
47
- "gitHead": "6a4d3da93d45115ad99861474a43c3f4a0b280a7"
47
+ "gitHead": "19f43c2d90d8b50860c3f8e487429779a386287d"
48
48
  }
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {FileSystem, isBrowser} from '@loaders.gl/loader-utils';
@@ -1,8 +1,13 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {MD5Hash} from '@loaders.gl/crypto';
5
- import {FileProvider} from '@loaders.gl/loader-utils';
6
+ import {
7
+ FileProvider,
8
+ concatenateArrayBuffers,
9
+ concatenateArrayBuffersFromArray
10
+ } from '@loaders.gl/loader-utils';
6
11
  import {makeZipCDHeaderIterator} from './parse-zip/cd-file-header';
7
12
 
8
13
  /**
@@ -54,3 +59,48 @@ export async function makeHashTableFromZipHeaders(
54
59
 
55
60
  return hashTable;
56
61
  }
62
+
63
+ /**
64
+ * creates hash file that later can be added to the SLPK archive
65
+ * @param fileProvider SLPK archive where we need to add hash file
66
+ * @returns ArrayBuffer containing hash file
67
+ */
68
+ export async function composeHashFile(fileProvider: FileProvider): Promise<ArrayBuffer> {
69
+ const hashArray = await makeHashTableFromZipHeaders(fileProvider);
70
+ const bufferArray = Object.entries(hashArray)
71
+ .map(([key, value]) => concatenateArrayBuffers(hexStringToBuffer(key), bigintToBuffer(value)))
72
+ .sort(compareHashes);
73
+ return concatenateArrayBuffersFromArray(bufferArray);
74
+ }
75
+
76
+ /**
77
+ * Function to compare md5 hashes according to https://github.com/Esri/i3s-spec/blob/master/docs/2.0/slpk_hashtable.pcsl.md
78
+ * @param arrA first hash to compare
79
+ * @param arrB second hash to compare
80
+ * @returns 0 if equal, negative number if a<b, pozitive if a>b
81
+ */
82
+ function compareHashes(arrA: ArrayBuffer, arrB: ArrayBuffer): number {
83
+ const a = new BigUint64Array(arrA);
84
+ const b = new BigUint64Array(arrB);
85
+
86
+ return Number(a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]);
87
+ }
88
+
89
+ /**
90
+ * converts hex string to buffer
91
+ * @param str hex string to convert
92
+ * @returns conversion result
93
+ */
94
+ function hexStringToBuffer(str: string): ArrayBuffer {
95
+ const byteArray = str.match(/../g)?.map((h) => parseInt(h, 16));
96
+ return new Uint8Array(byteArray ?? new Array(16)).buffer;
97
+ }
98
+
99
+ /**
100
+ * converts bigint to buffer
101
+ * @param n bigint to convert
102
+ * @returns convertion result
103
+ */
104
+ function bigintToBuffer(n: bigint): ArrayBuffer {
105
+ return new BigUint64Array([n]).buffer;
106
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  export {ZipLoader} from './zip-loader';
@@ -13,12 +14,14 @@ export {
13
14
  } from './parse-zip/cd-file-header';
14
15
  export {
15
16
  parseZipLocalFileHeader,
16
- signature as localHeaderSignature
17
+ signature as localHeaderSignature,
18
+ generateLocalHeader
17
19
  } from './parse-zip/local-file-header';
18
20
  export {parseEoCDRecord} from './parse-zip/end-of-central-directory';
19
21
  export {searchFromTheEnd} from './parse-zip/search-from-the-end';
22
+ export {addOneFile} from './parse-zip/zip-compozition';
20
23
 
21
24
  // export type {HashElement} from './hash-file-utility';
22
- export {parseHashTable, makeHashTableFromZipHeaders} from './hash-file-utility';
25
+ export {parseHashTable, makeHashTableFromZipHeaders, composeHashFile} from './hash-file-utility';
23
26
 
24
27
  export {ZipFileSystem} from './filesystems/zip-filesystem';
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the tar-js code base under MIT license
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the tar-js code base under MIT license
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  /**
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the tar-js code base under MIT license
@@ -1,10 +1,11 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {FileProvider, compareArrayBuffers, concatenateArrayBuffers} from '@loaders.gl/loader-utils';
5
6
  import {parseEoCDRecord} from './end-of-central-directory';
6
7
  import {ZipSignature} from './search-from-the-end';
7
- import {createZip64Info, NUMBER_SETTERS} from './zip64-info-generation';
8
+ import {createZip64Info, setFieldToNumber} from './zip64-info-generation';
8
9
 
9
10
  /**
10
11
  * zip central directory file header info
@@ -199,7 +200,7 @@ type GenerateCDOptions = {
199
200
  /** File size */
200
201
  length: number;
201
202
  /** Relative offset of local file header */
202
- offset: number;
203
+ offset: bigint;
203
204
  };
204
205
 
205
206
  /**
@@ -219,7 +220,7 @@ export function generateCDHeader(options: GenerateCDOptions): ArrayBuffer {
219
220
  const optionsToZip64: any = {};
220
221
  if (optionsToUse.offset >= 0xffffffff) {
221
222
  optionsToZip64.offset = optionsToUse.offset;
222
- optionsToUse.offset = 0xffffffff;
223
+ optionsToUse.offset = BigInt(0xffffffff);
223
224
  }
224
225
  if (optionsToUse.length >= 0xffffffff) {
225
226
  optionsToZip64.size = optionsToUse.length;
@@ -230,11 +231,12 @@ export function generateCDHeader(options: GenerateCDOptions): ArrayBuffer {
230
231
  zip64header = createZip64Info(optionsToZip64);
231
232
  optionsToUse.extraLength = zip64header.byteLength;
232
233
  }
233
- const header = new DataView(new ArrayBuffer(46));
234
+ const header = new DataView(new ArrayBuffer(Number(CD_FILE_NAME_OFFSET)));
234
235
 
235
236
  for (const field of ZIP_HEADER_FIELDS) {
236
- NUMBER_SETTERS[field.size](
237
+ setFieldToNumber(
237
238
  header,
239
+ field.size,
238
240
  field.offset,
239
241
  optionsToUse[field.name ?? ''] ?? field.default ?? 0
240
242
  );
@@ -1,8 +1,10 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {FileProvider, compareArrayBuffers} from '@loaders.gl/loader-utils';
5
6
  import {ZipSignature, searchFromTheEnd} from './search-from-the-end';
7
+ import {setFieldToNumber} from './zip64-info-generation';
6
8
 
7
9
  /**
8
10
  * End of central directory info
@@ -13,6 +15,18 @@ export type ZipEoCDRecord = {
13
15
  cdStartOffset: bigint;
14
16
  /** Relative offset of local file header */
15
17
  cdRecordsNumber: bigint;
18
+ offsets: ZipEoCDRecordOffsets;
19
+ };
20
+
21
+ /**
22
+ * End of central directory offsets
23
+ * according to https://en.wikipedia.org/wiki/ZIP_(file_format)
24
+ */
25
+ export type ZipEoCDRecordOffsets = {
26
+ zipEoCDOffset: bigint;
27
+
28
+ zip64EoCDOffset?: bigint;
29
+ zip64EoCDLocatorOffset?: bigint;
16
30
  };
17
31
 
18
32
  const eoCDSignature: ZipSignature = new Uint8Array([0x50, 0x4b, 0x05, 0x06]);
@@ -21,9 +35,13 @@ const zip64EoCDSignature = new Uint8Array([0x50, 0x4b, 0x06, 0x06]);
21
35
 
22
36
  // offsets accroding to https://en.wikipedia.org/wiki/ZIP_(file_format)
23
37
  const CD_RECORDS_NUMBER_OFFSET = 8n;
38
+ const CD_RECORDS_NUMBER_ON_DISC_OFFSET = 10n;
39
+ const CD_CD_BYTE_SIZE_OFFSET = 12n;
24
40
  const CD_START_OFFSET_OFFSET = 16n;
25
41
  const ZIP64_EOCD_START_OFFSET_OFFSET = 8n;
26
42
  const ZIP64_CD_RECORDS_NUMBER_OFFSET = 24n;
43
+ const ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET = 32n;
44
+ const ZIP64_CD_CD_BYTE_SIZE_OFFSET = 40n;
27
45
  const ZIP64_CD_START_OFFSET_OFFSET = 48n;
28
46
 
29
47
  /**
@@ -37,14 +55,12 @@ export const parseEoCDRecord = async (file: FileProvider): Promise<ZipEoCDRecord
37
55
  let cdRecordsNumber = BigInt(await file.getUint16(zipEoCDOffset + CD_RECORDS_NUMBER_OFFSET));
38
56
  let cdStartOffset = BigInt(await file.getUint32(zipEoCDOffset + CD_START_OFFSET_OFFSET));
39
57
 
40
- if (cdStartOffset === BigInt(0xffffffff) || cdRecordsNumber === BigInt(0xffffffff)) {
41
- const zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
58
+ let zip64EoCDLocatorOffset = zipEoCDOffset - 20n;
59
+ let zip64EoCDOffset = 0n;
42
60
 
43
- const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
44
- if (!compareArrayBuffers(magicBytes, zip64EoCDLocatorSignature)) {
45
- throw new Error('zip64 EoCD locator not found');
46
- }
47
- const zip64EoCDOffset = await file.getBigUint64(
61
+ const magicBytes = await file.slice(zip64EoCDLocatorOffset, zip64EoCDLocatorOffset + 4n);
62
+ if (compareArrayBuffers(magicBytes, zip64EoCDLocatorSignature)) {
63
+ zip64EoCDOffset = await file.getBigUint64(
48
64
  zip64EoCDLocatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET
49
65
  );
50
66
 
@@ -55,10 +71,84 @@ export const parseEoCDRecord = async (file: FileProvider): Promise<ZipEoCDRecord
55
71
 
56
72
  cdRecordsNumber = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_RECORDS_NUMBER_OFFSET);
57
73
  cdStartOffset = await file.getBigUint64(zip64EoCDOffset + ZIP64_CD_START_OFFSET_OFFSET);
74
+ } else {
75
+ zip64EoCDLocatorOffset = 0n;
58
76
  }
59
77
 
60
78
  return {
61
79
  cdRecordsNumber,
62
- cdStartOffset
80
+ cdStartOffset,
81
+ offsets: {
82
+ zip64EoCDOffset,
83
+ zip64EoCDLocatorOffset,
84
+ zipEoCDOffset
85
+ }
63
86
  };
64
87
  };
88
+
89
+ /**
90
+ * updates EoCD record to add more files to the archieve
91
+ * @param eocdBody buffer containing header
92
+ * @param oldEoCDOffsets info read from EoCD record befor updating
93
+ * @param newCDStartOffset CD start offset to be updated
94
+ * @param eocdStartOffset EoCD start offset to be updated
95
+ * @returns new EoCD header
96
+ */
97
+ export async function updateEoCD(
98
+ eocdBody: ArrayBuffer,
99
+ oldEoCDOffsets: ZipEoCDRecordOffsets,
100
+ newCDStartOffset: bigint,
101
+ eocdStartOffset: bigint,
102
+ newCDRecordsNumber: bigint
103
+ ): Promise<Uint8Array> {
104
+ const eocd = new DataView(eocdBody);
105
+
106
+ const classicEoCDOffset = oldEoCDOffsets.zip64EoCDOffset
107
+ ? oldEoCDOffsets.zipEoCDOffset - oldEoCDOffsets.zip64EoCDOffset
108
+ : 0n;
109
+
110
+ // updating classic EoCD record with new CD records number in general and on disc
111
+ if (Number(newCDRecordsNumber) <= 0xffff) {
112
+ setFieldToNumber(eocd, 2, classicEoCDOffset + CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
113
+ setFieldToNumber(
114
+ eocd,
115
+ 2,
116
+ classicEoCDOffset + CD_RECORDS_NUMBER_ON_DISC_OFFSET,
117
+ newCDRecordsNumber
118
+ );
119
+ }
120
+
121
+ // updating zip64 EoCD record with new size of CD
122
+ if (eocdStartOffset - newCDStartOffset <= 0xffffffff) {
123
+ setFieldToNumber(
124
+ eocd,
125
+ 4,
126
+ classicEoCDOffset + CD_CD_BYTE_SIZE_OFFSET,
127
+ eocdStartOffset - newCDStartOffset
128
+ );
129
+ }
130
+
131
+ // updating classic EoCD record with new CD start offset
132
+ if (newCDStartOffset < 0xffffffff) {
133
+ setFieldToNumber(eocd, 4, classicEoCDOffset + CD_START_OFFSET_OFFSET, newCDStartOffset);
134
+ }
135
+
136
+ // updating zip64 EoCD locator and record with new EoCD record start offset and cd records number
137
+ if (oldEoCDOffsets.zip64EoCDLocatorOffset && oldEoCDOffsets.zip64EoCDOffset) {
138
+ // updating zip64 EoCD locator with new EoCD record start offset
139
+ const locatorOffset = oldEoCDOffsets.zip64EoCDLocatorOffset - oldEoCDOffsets.zip64EoCDOffset;
140
+ setFieldToNumber(eocd, 8, locatorOffset + ZIP64_EOCD_START_OFFSET_OFFSET, eocdStartOffset);
141
+
142
+ // updating zip64 EoCD record with new cd start offset
143
+ setFieldToNumber(eocd, 8, ZIP64_CD_START_OFFSET_OFFSET, newCDStartOffset);
144
+
145
+ // updating zip64 EoCD record with new cd records number
146
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_OFFSET, newCDRecordsNumber);
147
+ setFieldToNumber(eocd, 8, ZIP64_CD_RECORDS_NUMBER_ON_DISC_OFFSET, newCDRecordsNumber);
148
+
149
+ // updating zip64 EoCD record with new size of CD
150
+ setFieldToNumber(eocd, 8, ZIP64_CD_CD_BYTE_SIZE_OFFSET, eocdStartOffset - newCDStartOffset);
151
+ }
152
+
153
+ return new Uint8Array(eocd.buffer);
154
+ }
@@ -1,8 +1,10 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
- import {FileProvider, compareArrayBuffers} from '@loaders.gl/loader-utils';
5
+ import {FileProvider, compareArrayBuffers, concatenateArrayBuffers} from '@loaders.gl/loader-utils';
5
6
  import {ZipSignature} from './search-from-the-end';
7
+ import {createZip64Info, setFieldToNumber} from './zip64-info-generation';
6
8
 
7
9
  /**
8
10
  * zip local file header info
@@ -94,3 +96,127 @@ export const parseZipLocalFileHeader = async (
94
96
  compressionMethod
95
97
  };
96
98
  };
99
+
100
+ /** info that can be placed into cd header */
101
+ type GenerateLocalOptions = {
102
+ /** CRC-32 of uncompressed data */
103
+ crc32: number;
104
+ /** File name */
105
+ fileName: string;
106
+ /** File size */
107
+ length: number;
108
+ };
109
+
110
+ /**
111
+ * generates local header for the file
112
+ * @param options info that can be placed into local header
113
+ * @returns buffer with header
114
+ */
115
+ export function generateLocalHeader(options: GenerateLocalOptions): ArrayBuffer {
116
+ const optionsToUse = {
117
+ ...options,
118
+ extraLength: 0,
119
+ fnlength: options.fileName.length
120
+ };
121
+
122
+ let zip64header: ArrayBuffer = new ArrayBuffer(0);
123
+
124
+ const optionsToZip64: any = {};
125
+ if (optionsToUse.length >= 0xffffffff) {
126
+ optionsToZip64.size = optionsToUse.length;
127
+ optionsToUse.length = 0xffffffff;
128
+ }
129
+
130
+ if (Object.keys(optionsToZip64).length) {
131
+ zip64header = createZip64Info(optionsToZip64);
132
+ optionsToUse.extraLength = zip64header.byteLength;
133
+ }
134
+
135
+ // base length without file name and extra info is static
136
+ const header = new DataView(new ArrayBuffer(Number(FILE_NAME_OFFSET)));
137
+
138
+ for (const field of ZIP_HEADER_FIELDS) {
139
+ setFieldToNumber(
140
+ header,
141
+ field.size,
142
+ field.offset,
143
+ optionsToUse[field.name ?? ''] ?? field.default ?? 0
144
+ );
145
+ }
146
+
147
+ const encodedName = new TextEncoder().encode(optionsToUse.fileName);
148
+
149
+ const resHeader = concatenateArrayBuffers(header.buffer, encodedName, zip64header);
150
+
151
+ return resHeader;
152
+ }
153
+
154
+ const ZIP_HEADER_FIELDS = [
155
+ // Local file header signature = 0x04034b50
156
+ {
157
+ offset: 0,
158
+ size: 4,
159
+ default: new DataView(signature.buffer).getUint32(0, true)
160
+ },
161
+ // Version needed to extract (minimum)
162
+ {
163
+ offset: 4,
164
+ size: 2,
165
+ default: 45
166
+ },
167
+ // General purpose bit flag
168
+ {
169
+ offset: 6,
170
+ size: 2,
171
+ default: 0
172
+ },
173
+ // Compression method
174
+ {
175
+ offset: 8,
176
+ size: 2,
177
+ default: 0
178
+ },
179
+ // File last modification time
180
+ {
181
+ offset: 10,
182
+ size: 2,
183
+ default: 0
184
+ },
185
+ // File last modification date
186
+ {
187
+ offset: 12,
188
+ size: 2,
189
+ default: 0
190
+ },
191
+ // CRC-32 of uncompressed data
192
+ {
193
+ offset: 14,
194
+ size: 4,
195
+ name: 'crc32'
196
+ },
197
+ // Compressed size (or 0xffffffff for ZIP64)
198
+ {
199
+ offset: 18,
200
+ size: 4,
201
+ name: 'length'
202
+ },
203
+ // Uncompressed size (or 0xffffffff for ZIP64)
204
+ {
205
+ offset: 22,
206
+ size: 4,
207
+ name: 'length'
208
+ },
209
+ // File name length (n)
210
+ {
211
+ offset: 26,
212
+ size: 2,
213
+ name: 'fnlength'
214
+ },
215
+ // Extra field length (m)
216
+ {
217
+ offset: 28,
218
+ size: 2,
219
+ default: 0,
220
+ name: 'extraLength'
221
+ }
222
+ ];