@metamask/snaps-utils 5.0.0 → 5.0.1

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/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [5.0.1]
10
+ ### Changed
11
+ - Improve base64 encoding/decoding speeds ([#1985](https://github.com/MetaMask/snaps/pull/1985))
12
+ - Bump several MetaMask dependencies ([#1989](https://github.com/MetaMask/snaps/pull/1989), [#1993](https://github.com/MetaMask/snaps/pull/1993))
13
+
9
14
  ## [5.0.0]
10
15
  ### Changed
11
16
  - Bump several MetaMask dependencies ([#1964](https://github.com/MetaMask/snaps/pull/1964))
@@ -117,7 +122,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
117
122
  - The version of the package no longer needs to match the version of all other
118
123
  MetaMask Snaps packages.
119
124
 
120
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@5.0.0...HEAD
125
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@5.0.1...HEAD
126
+ [5.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@5.0.0...@metamask/snaps-utils@5.0.1
121
127
  [5.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@4.0.1...@metamask/snaps-utils@5.0.0
122
128
  [4.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@4.0.0...@metamask/snaps-utils@4.0.1
123
129
  [4.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@3.3.0...@metamask/snaps-utils@4.0.0
@@ -10,14 +10,14 @@ Object.defineProperty(exports, "encodeAuxiliaryFile", {
10
10
  });
11
11
  const _snapssdk = require("@metamask/snaps-sdk");
12
12
  const _utils = require("@metamask/utils");
13
- const _base = require("@scure/base");
14
- function encodeAuxiliaryFile(value, encoding) {
13
+ const _base64 = require("./base64");
14
+ async function encodeAuxiliaryFile(value, encoding) {
15
15
  // Input is assumed to be the stored file in base64.
16
16
  if (encoding === _snapssdk.AuxiliaryFileEncoding.Base64) {
17
17
  return value;
18
18
  }
19
19
  // TODO: Use @metamask/utils for this
20
- const decoded = _base.base64.decode(value);
20
+ const decoded = await (0, _base64.decodeBase64)(value);
21
21
  if (encoding === _snapssdk.AuxiliaryFileEncoding.Utf8) {
22
22
  return (0, _utils.bytesToString)(decoded);
23
23
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auxiliary-files.ts"],"sourcesContent":["import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';\nimport { bytesToHex, bytesToString } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\n/**\n * Re-encodes an auxiliary file if needed depending on the requested file encoding.\n *\n * @param value - The base64 value stored for the auxiliary file.\n * @param encoding - The chosen encoding.\n * @returns The file encoded in the requested encoding.\n */\nexport function encodeAuxiliaryFile(\n value: string,\n encoding: AuxiliaryFileEncoding,\n) {\n // Input is assumed to be the stored file in base64.\n if (encoding === AuxiliaryFileEncoding.Base64) {\n return value;\n }\n\n // TODO: Use @metamask/utils for this\n const decoded = base64.decode(value);\n if (encoding === AuxiliaryFileEncoding.Utf8) {\n return bytesToString(decoded);\n }\n\n return bytesToHex(decoded);\n}\n"],"names":["encodeAuxiliaryFile","value","encoding","AuxiliaryFileEncoding","Base64","decoded","base64","decode","Utf8","bytesToString","bytesToHex"],"mappings":";;;;+BAWgBA;;;eAAAA;;;0BAXsB;uBACI;sBACnB;AAShB,SAASA,oBACdC,KAAa,EACbC,QAA+B;IAE/B,oDAAoD;IACpD,IAAIA,aAAaC,+BAAqB,CAACC,MAAM,EAAE;QAC7C,OAAOH;IACT;IAEA,qCAAqC;IACrC,MAAMI,UAAUC,YAAM,CAACC,MAAM,CAACN;IAC9B,IAAIC,aAAaC,+BAAqB,CAACK,IAAI,EAAE;QAC3C,OAAOC,IAAAA,oBAAa,EAACJ;IACvB;IAEA,OAAOK,IAAAA,iBAAU,EAACL;AACpB"}
1
+ {"version":3,"sources":["../../src/auxiliary-files.ts"],"sourcesContent":["import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';\nimport { bytesToHex, bytesToString } from '@metamask/utils';\n\nimport { decodeBase64 } from './base64';\n\n/**\n * Re-encodes an auxiliary file if needed depending on the requested file encoding.\n *\n * @param value - The base64 value stored for the auxiliary file.\n * @param encoding - The chosen encoding.\n * @returns The file encoded in the requested encoding.\n */\nexport async function encodeAuxiliaryFile(\n value: string,\n encoding: AuxiliaryFileEncoding,\n) {\n // Input is assumed to be the stored file in base64.\n if (encoding === AuxiliaryFileEncoding.Base64) {\n return value;\n }\n\n // TODO: Use @metamask/utils for this\n const decoded = await decodeBase64(value);\n if (encoding === AuxiliaryFileEncoding.Utf8) {\n return bytesToString(decoded);\n }\n\n return bytesToHex(decoded);\n}\n"],"names":["encodeAuxiliaryFile","value","encoding","AuxiliaryFileEncoding","Base64","decoded","decodeBase64","Utf8","bytesToString","bytesToHex"],"mappings":";;;;+BAYsBA;;;eAAAA;;;0BAZgB;uBACI;wBAEb;AAStB,eAAeA,oBACpBC,KAAa,EACbC,QAA+B;IAE/B,oDAAoD;IACpD,IAAIA,aAAaC,+BAAqB,CAACC,MAAM,EAAE;QAC7C,OAAOH;IACT;IAEA,qCAAqC;IACrC,MAAMI,UAAU,MAAMC,IAAAA,oBAAY,EAACL;IACnC,IAAIC,aAAaC,+BAAqB,CAACI,IAAI,EAAE;QAC3C,OAAOC,IAAAA,oBAAa,EAACH;IACvB;IAEA,OAAOI,IAAAA,iBAAU,EAACJ;AACpB"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ encodeBase64: function() {
13
+ return encodeBase64;
14
+ },
15
+ decodeBase64: function() {
16
+ return decodeBase64;
17
+ }
18
+ });
19
+ const _utils = require("@metamask/utils");
20
+ const _bytes = require("./bytes");
21
+ async function encodeBase64(input) {
22
+ const bytes = (0, _bytes.getBytes)(input);
23
+ // In the browser, FileReader is much faster than bytesToBase64.
24
+ if ('FileReader' in globalThis) {
25
+ return await new Promise((resolve, reject)=>{
26
+ const reader = Object.assign(new FileReader(), {
27
+ onload: ()=>resolve(reader.result.replace('data:application/octet-stream;base64,', '')),
28
+ onerror: ()=>reject(reader.error)
29
+ });
30
+ reader.readAsDataURL(new File([
31
+ bytes
32
+ ], '', {
33
+ type: 'application/octet-stream'
34
+ }));
35
+ });
36
+ }
37
+ return (0, _utils.bytesToBase64)(bytes);
38
+ }
39
+ async function decodeBase64(base64) {
40
+ const response = await fetch(`data:application/octet-stream;base64,${base64}`);
41
+ return new Uint8Array(await response.arrayBuffer());
42
+ }
43
+
44
+ //# sourceMappingURL=base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/base64.ts"],"sourcesContent":["import { bytesToBase64 } from '@metamask/utils';\n\nimport { getBytes } from './bytes';\nimport type { VirtualFile } from './virtual-file';\n\n/**\n * Provides fast, asynchronous base64 encoding.\n *\n * @param input - The input value, assumed to be coercable to bytes.\n * @returns A base64 string.\n */\nexport async function encodeBase64(input: Uint8Array | VirtualFile | string) {\n const bytes = getBytes(input);\n // In the browser, FileReader is much faster than bytesToBase64.\n if ('FileReader' in globalThis) {\n return await new Promise((resolve, reject) => {\n const reader = Object.assign(new FileReader(), {\n onload: () =>\n resolve(\n (reader.result as string).replace(\n 'data:application/octet-stream;base64,',\n '',\n ),\n ),\n onerror: () => reject(reader.error),\n });\n reader.readAsDataURL(\n new File([bytes], '', { type: 'application/octet-stream' }),\n );\n });\n }\n return bytesToBase64(bytes);\n}\n\n/**\n * Provides fast, asynchronous base64 decoding.\n *\n * @param base64 - A base64 string.\n * @returns A Uint8Array of bytes.\n */\nexport async function decodeBase64(base64: string) {\n const response = await fetch(\n `data:application/octet-stream;base64,${base64}`,\n );\n return new Uint8Array(await response.arrayBuffer());\n}\n"],"names":["encodeBase64","decodeBase64","input","bytes","getBytes","globalThis","Promise","resolve","reject","reader","Object","assign","FileReader","onload","result","replace","onerror","error","readAsDataURL","File","type","bytesToBase64","base64","response","fetch","Uint8Array","arrayBuffer"],"mappings":";;;;;;;;;;;IAWsBA,YAAY;eAAZA;;IA6BAC,YAAY;eAAZA;;;uBAxCQ;uBAEL;AASlB,eAAeD,aAAaE,KAAwC;IACzE,MAAMC,QAAQC,IAAAA,eAAQ,EAACF;IACvB,gEAAgE;IAChE,IAAI,gBAAgBG,YAAY;QAC9B,OAAO,MAAM,IAAIC,QAAQ,CAACC,SAASC;YACjC,MAAMC,SAASC,OAAOC,MAAM,CAAC,IAAIC,cAAc;gBAC7CC,QAAQ,IACNN,QACE,AAACE,OAAOK,MAAM,CAAYC,OAAO,CAC/B,yCACA;gBAGNC,SAAS,IAAMR,OAAOC,OAAOQ,KAAK;YACpC;YACAR,OAAOS,aAAa,CAClB,IAAIC,KAAK;gBAAChB;aAAM,EAAE,IAAI;gBAAEiB,MAAM;YAA2B;QAE7D;IACF;IACA,OAAOC,IAAAA,oBAAa,EAAClB;AACvB;AAQO,eAAeF,aAAaqB,MAAc;IAC/C,MAAMC,WAAW,MAAMC,MACrB,CAAC,qCAAqC,EAAEF,OAAO,CAAC;IAElD,OAAO,IAAIG,WAAW,MAAMF,SAASG,WAAW;AAClD"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "getBytes", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return getBytes;
9
+ }
10
+ });
11
+ const _utils = require("@metamask/utils");
12
+ const _virtualfile = require("./virtual-file");
13
+ function getBytes(bytes) {
14
+ // Unwrap VirtualFiles to extract the content
15
+ // The content is then either a string or Uint8Array
16
+ const unwrapped = bytes instanceof _virtualfile.VirtualFile ? bytes.value : bytes;
17
+ if (typeof unwrapped === 'string') {
18
+ return (0, _utils.stringToBytes)(unwrapped);
19
+ }
20
+ return unwrapped;
21
+ }
22
+
23
+ //# sourceMappingURL=bytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bytes.ts"],"sourcesContent":["import { stringToBytes } from '@metamask/utils';\n\nimport { VirtualFile } from './virtual-file';\n\n/**\n * Convert a bytes-like input value to a Uint8Array.\n *\n * @param bytes - A bytes-like value.\n * @returns The input value converted to a Uint8Array if necessary.\n */\nexport function getBytes(bytes: VirtualFile | Uint8Array | string): Uint8Array {\n // Unwrap VirtualFiles to extract the content\n // The content is then either a string or Uint8Array\n const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;\n\n if (typeof unwrapped === 'string') {\n return stringToBytes(unwrapped);\n }\n\n return unwrapped;\n}\n"],"names":["getBytes","bytes","unwrapped","VirtualFile","value","stringToBytes"],"mappings":";;;;+BAUgBA;;;eAAAA;;;uBAVc;6BAEF;AAQrB,SAASA,SAASC,KAAwC;IAC/D,6CAA6C;IAC7C,oDAAoD;IACpD,MAAMC,YAAYD,iBAAiBE,wBAAW,GAAGF,MAAMG,KAAK,GAAGH;IAE/D,IAAI,OAAOC,cAAc,UAAU;QACjC,OAAOG,IAAAA,oBAAa,EAACH;IACvB;IAEA,OAAOA;AACT"}
@@ -9,9 +9,6 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
- getChecksumBytes: function() {
13
- return getChecksumBytes;
14
- },
15
12
  checksum: function() {
16
13
  return checksum;
17
14
  },
@@ -21,18 +18,9 @@ _export(exports, {
21
18
  });
22
19
  const _utils = require("@metamask/utils");
23
20
  const _sha256 = require("@noble/hashes/sha256");
24
- const _VirtualFile = require("./virtual-file/VirtualFile");
25
- function getChecksumBytes(bytes) {
26
- // Unwrap VirtualFiles to extract the content
27
- // The content is then either a string or Uint8Array
28
- const unwrapped = bytes instanceof _VirtualFile.VirtualFile ? bytes.value : bytes;
29
- if (typeof unwrapped === 'string') {
30
- return (0, _utils.stringToBytes)(unwrapped);
31
- }
32
- return unwrapped;
33
- }
21
+ const _bytes = require("./bytes");
34
22
  async function checksum(bytes) {
35
- const value = getChecksumBytes(bytes);
23
+ const value = (0, _bytes.getBytes)(bytes);
36
24
  // Use crypto.subtle.digest whenever possible as it is faster.
37
25
  if ('crypto' in globalThis && typeof globalThis.crypto === 'object' && crypto.subtle?.digest) {
38
26
  return new Uint8Array(await crypto.subtle.digest('SHA-256', value));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/checksum.ts"],"sourcesContent":["import { assert, concatBytes, stringToBytes } from '@metamask/utils';\nimport { sha256 } from '@noble/hashes/sha256';\n\nimport { VirtualFile } from './virtual-file/VirtualFile';\n\n/**\n * Convert an input value to a Uint8Array for use in a checksum.\n *\n * @param bytes - A value to use for a checksum calculation.\n * @returns The input value converted to a Uint8Array if necessary.\n */\nexport function getChecksumBytes(\n bytes: VirtualFile | Uint8Array | string,\n): Uint8Array {\n // Unwrap VirtualFiles to extract the content\n // The content is then either a string or Uint8Array\n const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;\n\n if (typeof unwrapped === 'string') {\n return stringToBytes(unwrapped);\n }\n\n return unwrapped;\n}\n\n/**\n * Calculates checksum for a single byte array.\n *\n * @param bytes - The byte array to calculate the checksum for.\n * @returns A single sha-256 checksum.\n */\nexport async function checksum(\n bytes: VirtualFile | Uint8Array | string,\n): Promise<Uint8Array> {\n const value = getChecksumBytes(bytes);\n // Use crypto.subtle.digest whenever possible as it is faster.\n if (\n 'crypto' in globalThis &&\n typeof globalThis.crypto === 'object' &&\n crypto.subtle?.digest\n ) {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', value));\n }\n return sha256(value);\n}\n\n/**\n * Calculates checksum over multiple files in a reproducible way.\n *\n * 1. Sort all the files by their paths.\n * 2. Calculate sha-256 checksum of each file separately.\n * 3. Concatenate all the checksums into one buffer and sha-256 that buffer.\n *\n * The sorting of paths is done using {@link https://tc39.es/ecma262/#sec-islessthan UTF-16 Code Units}.\n *\n * @param files - The files over which to calculate the checksum.\n * @returns A single sha-256 checksum.\n */\nexport async function checksumFiles(files: VirtualFile[]) {\n const checksums = await Promise.all(\n [...files]\n .sort((a, b) => {\n assert(a.path !== b.path, 'Tried to sort files with non-unique paths.');\n if (a.path < b.path) {\n return -1;\n }\n return 1;\n })\n .map(async (file) => checksum(file)),\n );\n\n return checksum(concatBytes(checksums));\n}\n"],"names":["getChecksumBytes","checksum","checksumFiles","bytes","unwrapped","VirtualFile","value","stringToBytes","globalThis","crypto","subtle","digest","Uint8Array","sha256","files","checksums","Promise","all","sort","a","b","assert","path","map","file","concatBytes"],"mappings":";;;;;;;;;;;IAWgBA,gBAAgB;eAAhBA;;IAoBMC,QAAQ;eAARA;;IA2BAC,aAAa;eAAbA;;;uBA1D6B;wBAC5B;6BAEK;AAQrB,SAASF,iBACdG,KAAwC;IAExC,6CAA6C;IAC7C,oDAAoD;IACpD,MAAMC,YAAYD,iBAAiBE,wBAAW,GAAGF,MAAMG,KAAK,GAAGH;IAE/D,IAAI,OAAOC,cAAc,UAAU;QACjC,OAAOG,IAAAA,oBAAa,EAACH;IACvB;IAEA,OAAOA;AACT;AAQO,eAAeH,SACpBE,KAAwC;IAExC,MAAMG,QAAQN,iBAAiBG;IAC/B,8DAA8D;IAC9D,IACE,YAAYK,cACZ,OAAOA,WAAWC,MAAM,KAAK,YAC7BA,OAAOC,MAAM,EAAEC,QACf;QACA,OAAO,IAAIC,WAAW,MAAMH,OAAOC,MAAM,CAACC,MAAM,CAAC,WAAWL;IAC9D;IACA,OAAOO,IAAAA,cAAM,EAACP;AAChB;AAcO,eAAeJ,cAAcY,KAAoB;IACtD,MAAMC,YAAY,MAAMC,QAAQC,GAAG,CACjC;WAAIH;KAAM,CACPI,IAAI,CAAC,CAACC,GAAGC;QACRC,IAAAA,aAAM,EAACF,EAAEG,IAAI,KAAKF,EAAEE,IAAI,EAAE;QAC1B,IAAIH,EAAEG,IAAI,GAAGF,EAAEE,IAAI,EAAE;YACnB,OAAO,CAAC;QACV;QACA,OAAO;IACT,GACCC,GAAG,CAAC,OAAOC,OAASvB,SAASuB;IAGlC,OAAOvB,SAASwB,IAAAA,kBAAW,EAACV;AAC9B"}
1
+ {"version":3,"sources":["../../src/checksum.ts"],"sourcesContent":["import { assert, concatBytes } from '@metamask/utils';\nimport { sha256 } from '@noble/hashes/sha256';\n\nimport { getBytes } from './bytes';\nimport type { VirtualFile } from './virtual-file/VirtualFile';\n\n/**\n * Calculates checksum for a single byte array.\n *\n * @param bytes - The byte array to calculate the checksum for.\n * @returns A single sha-256 checksum.\n */\nexport async function checksum(\n bytes: VirtualFile | Uint8Array | string,\n): Promise<Uint8Array> {\n const value = getBytes(bytes);\n // Use crypto.subtle.digest whenever possible as it is faster.\n if (\n 'crypto' in globalThis &&\n typeof globalThis.crypto === 'object' &&\n crypto.subtle?.digest\n ) {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', value));\n }\n return sha256(value);\n}\n\n/**\n * Calculates checksum over multiple files in a reproducible way.\n *\n * 1. Sort all the files by their paths.\n * 2. Calculate sha-256 checksum of each file separately.\n * 3. Concatenate all the checksums into one buffer and sha-256 that buffer.\n *\n * The sorting of paths is done using {@link https://tc39.es/ecma262/#sec-islessthan UTF-16 Code Units}.\n *\n * @param files - The files over which to calculate the checksum.\n * @returns A single sha-256 checksum.\n */\nexport async function checksumFiles(files: VirtualFile[]) {\n const checksums = await Promise.all(\n [...files]\n .sort((a, b) => {\n assert(a.path !== b.path, 'Tried to sort files with non-unique paths.');\n if (a.path < b.path) {\n return -1;\n }\n return 1;\n })\n .map(async (file) => checksum(file)),\n );\n\n return checksum(concatBytes(checksums));\n}\n"],"names":["checksum","checksumFiles","bytes","value","getBytes","globalThis","crypto","subtle","digest","Uint8Array","sha256","files","checksums","Promise","all","sort","a","b","assert","path","map","file","concatBytes"],"mappings":";;;;;;;;;;;IAYsBA,QAAQ;eAARA;;IA2BAC,aAAa;eAAbA;;;uBAvCc;wBACb;uBAEE;AASlB,eAAeD,SACpBE,KAAwC;IAExC,MAAMC,QAAQC,IAAAA,eAAQ,EAACF;IACvB,8DAA8D;IAC9D,IACE,YAAYG,cACZ,OAAOA,WAAWC,MAAM,KAAK,YAC7BA,OAAOC,MAAM,EAAEC,QACf;QACA,OAAO,IAAIC,WAAW,MAAMH,OAAOC,MAAM,CAACC,MAAM,CAAC,WAAWL;IAC9D;IACA,OAAOO,IAAAA,cAAM,EAACP;AAChB;AAcO,eAAeF,cAAcU,KAAoB;IACtD,MAAMC,YAAY,MAAMC,QAAQC,GAAG,CACjC;WAAIH;KAAM,CACPI,IAAI,CAAC,CAACC,GAAGC;QACRC,IAAAA,aAAM,EAACF,EAAEG,IAAI,KAAKF,EAAEE,IAAI,EAAE;QAC1B,IAAIH,EAAEG,IAAI,GAAGF,EAAEE,IAAI,EAAE;YACnB,OAAO,CAAC;QACV;QACA,OAAO;IACT,GACCC,GAAG,CAAC,OAAOC,OAASrB,SAASqB;IAGlC,OAAOrB,SAASsB,IAAAA,kBAAW,EAACV;AAC9B"}
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  _export_star(require("./array"), exports);
6
6
  _export_star(require("./auxiliary-files"), exports);
7
+ _export_star(require("./base64"), exports);
8
+ _export_star(require("./bytes"), exports);
7
9
  _export_star(require("./caveats"), exports);
8
10
  _export_star(require("./checksum"), exports);
9
11
  _export_star(require("./cronjob"), exports);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.browser.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './caveats';\nexport * from './checksum';\nexport * from './cronjob';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './errors';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest/index.browser';\nexport * from './namespace';\nexport * from './path';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file/index.browser';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
1
+ {"version":3,"sources":["../../src/index.browser.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './base64';\nexport * from './bytes';\nexport * from './caveats';\nexport * from './checksum';\nexport * from './cronjob';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './errors';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest/index.browser';\nexport * from './namespace';\nexport * from './path';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file/index.browser';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
package/dist/cjs/index.js CHANGED
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  _export_star(require("./array"), exports);
6
6
  _export_star(require("./auxiliary-files"), exports);
7
+ _export_star(require("./base64"), exports);
8
+ _export_star(require("./bytes"), exports);
7
9
  _export_star(require("./caveats"), exports);
8
10
  _export_star(require("./cronjob"), exports);
9
11
  _export_star(require("./checksum"), exports);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './caveats';\nexport * from './cronjob';\nexport * from './checksum';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './eval';\nexport * from './errors';\nexport * from './fs';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest';\nexport * from './mock';\nexport * from './namespace';\nexport * from './npm';\nexport * from './path';\nexport * from './post-process';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './base64';\nexport * from './bytes';\nexport * from './caveats';\nexport * from './cronjob';\nexport * from './checksum';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './eval';\nexport * from './errors';\nexport * from './fs';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest';\nexport * from './mock';\nexport * from './namespace';\nexport * from './npm';\nexport * from './path';\nexport * from './post-process';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
@@ -40,6 +40,7 @@ class VirtualFile {
40
40
  } else if (this.value instanceof Uint8Array && encoding === 'hex') {
41
41
  return (0, _utils.bytesToHex)(this.value);
42
42
  } else if (this.value instanceof Uint8Array && encoding === 'base64') {
43
+ // For large files, this is quite slow, instead use `encodeBase64()`
43
44
  // TODO: Use @metamask/utils for this
44
45
  return _base.base64.encode(this.value);
45
46
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/virtual-file/VirtualFile.ts"],"sourcesContent":["// TODO(ritave): Move into separate package @metamask/vfile / @metamask/utils + @metamask/to-vfile when passes code review\n// TODO(ritave): Streaming vfile contents similar to vinyl maybe?\n// TODO(ritave): Move fixing manifest in cli and bundler plugins to write messages to vfile\n// similar to unified instead of throwing \"ProgrammaticallyFixableErrors\".\n//\n// Using https://github.com/vfile/vfile would be helpful, but they only support ESM and we need to support CommonJS.\n// https://github.com/gulpjs/vinyl is also good, but they normalize paths, which we can't do, because\n// we're calculating checksums based on original path.\nimport { assert, bytesToHex } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\nimport { deepClone } from '../deep-clone';\n\n/**\n * This map registers the type of the {@link VirtualFile.data} key of a {@link VirtualFile}.\n *\n * This type can be augmented to register custom `data` types.\n *\n * @example\n * declare module '@metamask/snaps-utils' {\n * interface DataMap {\n * // `file.data.name` is typed as `string`\n * name: string\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-empty-interface\nexport interface DataMap {}\n\nexport type Value = string | Uint8Array;\nexport type Compatible<Result = unknown> =\n | string\n | Uint8Array\n | Options<Result>;\nexport type Data = Record<string, unknown> & Partial<DataMap>;\nexport type Options<Result = unknown> = {\n value: Value;\n path?: string;\n data?: Data;\n result?: Result;\n};\n\nexport class VirtualFile<Result = unknown> {\n constructor(value?: Compatible<Result>) {\n let options: Options | undefined;\n if (typeof value === 'string' || value instanceof Uint8Array) {\n options = { value };\n } else {\n options = value;\n }\n\n this.value = options?.value ?? '';\n // This situations happens when there's no .result used,\n // we expect the file to have default generic in that situation:\n // VirtualFile<unknown> which will handle undefined properly\n //\n // While not 100% type safe, it'll be way less frustrating to work with.\n // The alternative would be to have VirtualFile.result be Result | undefined\n // and that would result in needing to branch out and check in all situations.\n //\n // In short, optimizing for most common use case.\n this.result = options?.result ?? (undefined as any);\n this.data = options?.data ?? {};\n this.path = options?.path ?? '/';\n }\n\n value: Value;\n\n result: Result;\n\n data: Data;\n\n path: string;\n\n toString(encoding?: string) {\n if (typeof this.value === 'string') {\n assert(encoding === undefined, 'Tried to encode string.');\n return this.value;\n } else if (this.value instanceof Uint8Array && encoding === 'hex') {\n return bytesToHex(this.value);\n } else if (this.value instanceof Uint8Array && encoding === 'base64') {\n // TODO: Use @metamask/utils for this\n return base64.encode(this.value);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(this.value);\n }\n\n clone() {\n const vfile = new VirtualFile<Result>();\n if (typeof this.value === 'string') {\n vfile.value = this.value;\n } else {\n // deep-clone doesn't clone Buffer properly, even if it's a sub-class of Uint8Array\n vfile.value = this.value.slice(0);\n }\n vfile.result = deepClone(this.result);\n vfile.data = deepClone(this.data);\n vfile.path = this.path;\n return vfile;\n }\n}\n"],"names":["VirtualFile","toString","encoding","value","assert","undefined","Uint8Array","bytesToHex","base64","encode","decoder","TextDecoder","decode","clone","vfile","slice","result","deepClone","data","path","constructor","options"],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;;;;;+BAmCzCA;;;eAAAA;;;uBAlCsB;sBACZ;2BAEG;;;;;;;;;;;;;;AA+BnB,MAAMA;IAgCXC,SAASC,QAAiB,EAAE;QAC1B,IAAI,OAAO,IAAI,CAACC,KAAK,KAAK,UAAU;YAClCC,IAAAA,aAAM,EAACF,aAAaG,WAAW;YAC/B,OAAO,IAAI,CAACF,KAAK;QACnB,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYG,cAAcJ,aAAa,OAAO;YACjE,OAAOK,IAAAA,iBAAU,EAAC,IAAI,CAACJ,KAAK;QAC9B,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYG,cAAcJ,aAAa,UAAU;YACpE,qCAAqC;YACrC,OAAOM,YAAM,CAACC,MAAM,CAAC,IAAI,CAACN,KAAK;QACjC;QACA,MAAMO,UAAU,IAAIC,YAAYT;QAChC,OAAOQ,QAAQE,MAAM,CAAC,IAAI,CAACT,KAAK;IAClC;IAEAU,QAAQ;QACN,MAAMC,QAAQ,IAAId;QAClB,IAAI,OAAO,IAAI,CAACG,KAAK,KAAK,UAAU;YAClCW,MAAMX,KAAK,GAAG,IAAI,CAACA,KAAK;QAC1B,OAAO;YACL,mFAAmF;YACnFW,MAAMX,KAAK,GAAG,IAAI,CAACA,KAAK,CAACY,KAAK,CAAC;QACjC;QACAD,MAAME,MAAM,GAAGC,IAAAA,oBAAS,EAAC,IAAI,CAACD,MAAM;QACpCF,MAAMI,IAAI,GAAGD,IAAAA,oBAAS,EAAC,IAAI,CAACC,IAAI;QAChCJ,MAAMK,IAAI,GAAG,IAAI,CAACA,IAAI;QACtB,OAAOL;IACT;IAzDAM,YAAYjB,KAA0B,CAAE;QAuBxCA,uBAAAA,SAAAA,KAAAA;QAEAa,uBAAAA,UAAAA,KAAAA;QAEAE,uBAAAA,QAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QA5BE,IAAIE;QACJ,IAAI,OAAOlB,UAAU,YAAYA,iBAAiBG,YAAY;YAC5De,UAAU;gBAAElB;YAAM;QACpB,OAAO;YACLkB,UAAUlB;QACZ;QAEA,IAAI,CAACA,KAAK,GAAGkB,SAASlB,SAAS;QAC/B,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAACa,MAAM,GAAGK,SAASL,UAAWX;QAClC,IAAI,CAACa,IAAI,GAAGG,SAASH,QAAQ,CAAC;QAC9B,IAAI,CAACC,IAAI,GAAGE,SAASF,QAAQ;IAC/B;AAqCF"}
1
+ {"version":3,"sources":["../../../src/virtual-file/VirtualFile.ts"],"sourcesContent":["// TODO(ritave): Move into separate package @metamask/vfile / @metamask/utils + @metamask/to-vfile when passes code review\n// TODO(ritave): Streaming vfile contents similar to vinyl maybe?\n// TODO(ritave): Move fixing manifest in cli and bundler plugins to write messages to vfile\n// similar to unified instead of throwing \"ProgrammaticallyFixableErrors\".\n//\n// Using https://github.com/vfile/vfile would be helpful, but they only support ESM and we need to support CommonJS.\n// https://github.com/gulpjs/vinyl is also good, but they normalize paths, which we can't do, because\n// we're calculating checksums based on original path.\nimport { assert, bytesToHex } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\nimport { deepClone } from '../deep-clone';\n\n/**\n * This map registers the type of the {@link VirtualFile.data} key of a {@link VirtualFile}.\n *\n * This type can be augmented to register custom `data` types.\n *\n * @example\n * declare module '@metamask/snaps-utils' {\n * interface DataMap {\n * // `file.data.name` is typed as `string`\n * name: string\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-empty-interface\nexport interface DataMap {}\n\nexport type Value = string | Uint8Array;\nexport type Compatible<Result = unknown> =\n | string\n | Uint8Array\n | Options<Result>;\nexport type Data = Record<string, unknown> & Partial<DataMap>;\nexport type Options<Result = unknown> = {\n value: Value;\n path?: string;\n data?: Data;\n result?: Result;\n};\n\nexport class VirtualFile<Result = unknown> {\n constructor(value?: Compatible<Result>) {\n let options: Options | undefined;\n if (typeof value === 'string' || value instanceof Uint8Array) {\n options = { value };\n } else {\n options = value;\n }\n\n this.value = options?.value ?? '';\n // This situations happens when there's no .result used,\n // we expect the file to have default generic in that situation:\n // VirtualFile<unknown> which will handle undefined properly\n //\n // While not 100% type safe, it'll be way less frustrating to work with.\n // The alternative would be to have VirtualFile.result be Result | undefined\n // and that would result in needing to branch out and check in all situations.\n //\n // In short, optimizing for most common use case.\n this.result = options?.result ?? (undefined as any);\n this.data = options?.data ?? {};\n this.path = options?.path ?? '/';\n }\n\n value: Value;\n\n result: Result;\n\n data: Data;\n\n path: string;\n\n toString(encoding?: string) {\n if (typeof this.value === 'string') {\n assert(encoding === undefined, 'Tried to encode string.');\n return this.value;\n } else if (this.value instanceof Uint8Array && encoding === 'hex') {\n return bytesToHex(this.value);\n } else if (this.value instanceof Uint8Array && encoding === 'base64') {\n // For large files, this is quite slow, instead use `encodeBase64()`\n // TODO: Use @metamask/utils for this\n return base64.encode(this.value);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(this.value);\n }\n\n clone() {\n const vfile = new VirtualFile<Result>();\n if (typeof this.value === 'string') {\n vfile.value = this.value;\n } else {\n // deep-clone doesn't clone Buffer properly, even if it's a sub-class of Uint8Array\n vfile.value = this.value.slice(0);\n }\n vfile.result = deepClone(this.result);\n vfile.data = deepClone(this.data);\n vfile.path = this.path;\n return vfile;\n }\n}\n"],"names":["VirtualFile","toString","encoding","value","assert","undefined","Uint8Array","bytesToHex","base64","encode","decoder","TextDecoder","decode","clone","vfile","slice","result","deepClone","data","path","constructor","options"],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;;;;;+BAmCzCA;;;eAAAA;;;uBAlCsB;sBACZ;2BAEG;;;;;;;;;;;;;;AA+BnB,MAAMA;IAgCXC,SAASC,QAAiB,EAAE;QAC1B,IAAI,OAAO,IAAI,CAACC,KAAK,KAAK,UAAU;YAClCC,IAAAA,aAAM,EAACF,aAAaG,WAAW;YAC/B,OAAO,IAAI,CAACF,KAAK;QACnB,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYG,cAAcJ,aAAa,OAAO;YACjE,OAAOK,IAAAA,iBAAU,EAAC,IAAI,CAACJ,KAAK;QAC9B,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYG,cAAcJ,aAAa,UAAU;YACpE,oEAAoE;YACpE,qCAAqC;YACrC,OAAOM,YAAM,CAACC,MAAM,CAAC,IAAI,CAACN,KAAK;QACjC;QACA,MAAMO,UAAU,IAAIC,YAAYT;QAChC,OAAOQ,QAAQE,MAAM,CAAC,IAAI,CAACT,KAAK;IAClC;IAEAU,QAAQ;QACN,MAAMC,QAAQ,IAAId;QAClB,IAAI,OAAO,IAAI,CAACG,KAAK,KAAK,UAAU;YAClCW,MAAMX,KAAK,GAAG,IAAI,CAACA,KAAK;QAC1B,OAAO;YACL,mFAAmF;YACnFW,MAAMX,KAAK,GAAG,IAAI,CAACA,KAAK,CAACY,KAAK,CAAC;QACjC;QACAD,MAAME,MAAM,GAAGC,IAAAA,oBAAS,EAAC,IAAI,CAACD,MAAM;QACpCF,MAAMI,IAAI,GAAGD,IAAAA,oBAAS,EAAC,IAAI,CAACC,IAAI;QAChCJ,MAAMK,IAAI,GAAG,IAAI,CAACA,IAAI;QACtB,OAAOL;IACT;IA1DAM,YAAYjB,KAA0B,CAAE;QAuBxCA,uBAAAA,SAAAA,KAAAA;QAEAa,uBAAAA,UAAAA,KAAAA;QAEAE,uBAAAA,QAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QA5BE,IAAIE;QACJ,IAAI,OAAOlB,UAAU,YAAYA,iBAAiBG,YAAY;YAC5De,UAAU;gBAAElB;YAAM;QACpB,OAAO;YACLkB,UAAUlB;QACZ;QAEA,IAAI,CAACA,KAAK,GAAGkB,SAASlB,SAAS;QAC/B,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAACa,MAAM,GAAGK,SAASL,UAAWX;QAClC,IAAI,CAACa,IAAI,GAAGG,SAASH,QAAQ,CAAC;QAC9B,IAAI,CAACC,IAAI,GAAGE,SAASF,QAAQ;IAC/B;AAsCF"}
@@ -1,19 +1,19 @@
1
1
  import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';
2
2
  import { bytesToHex, bytesToString } from '@metamask/utils';
3
- import { base64 } from '@scure/base';
3
+ import { decodeBase64 } from './base64';
4
4
  /**
5
5
  * Re-encodes an auxiliary file if needed depending on the requested file encoding.
6
6
  *
7
7
  * @param value - The base64 value stored for the auxiliary file.
8
8
  * @param encoding - The chosen encoding.
9
9
  * @returns The file encoded in the requested encoding.
10
- */ export function encodeAuxiliaryFile(value, encoding) {
10
+ */ export async function encodeAuxiliaryFile(value, encoding) {
11
11
  // Input is assumed to be the stored file in base64.
12
12
  if (encoding === AuxiliaryFileEncoding.Base64) {
13
13
  return value;
14
14
  }
15
15
  // TODO: Use @metamask/utils for this
16
- const decoded = base64.decode(value);
16
+ const decoded = await decodeBase64(value);
17
17
  if (encoding === AuxiliaryFileEncoding.Utf8) {
18
18
  return bytesToString(decoded);
19
19
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auxiliary-files.ts"],"sourcesContent":["import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';\nimport { bytesToHex, bytesToString } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\n/**\n * Re-encodes an auxiliary file if needed depending on the requested file encoding.\n *\n * @param value - The base64 value stored for the auxiliary file.\n * @param encoding - The chosen encoding.\n * @returns The file encoded in the requested encoding.\n */\nexport function encodeAuxiliaryFile(\n value: string,\n encoding: AuxiliaryFileEncoding,\n) {\n // Input is assumed to be the stored file in base64.\n if (encoding === AuxiliaryFileEncoding.Base64) {\n return value;\n }\n\n // TODO: Use @metamask/utils for this\n const decoded = base64.decode(value);\n if (encoding === AuxiliaryFileEncoding.Utf8) {\n return bytesToString(decoded);\n }\n\n return bytesToHex(decoded);\n}\n"],"names":["AuxiliaryFileEncoding","bytesToHex","bytesToString","base64","encodeAuxiliaryFile","value","encoding","Base64","decoded","decode","Utf8"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,sBAAsB;AAC5D,SAASC,UAAU,EAAEC,aAAa,QAAQ,kBAAkB;AAC5D,SAASC,MAAM,QAAQ,cAAc;AAErC;;;;;;CAMC,GACD,OAAO,SAASC,oBACdC,KAAa,EACbC,QAA+B;IAE/B,oDAAoD;IACpD,IAAIA,aAAaN,sBAAsBO,MAAM,EAAE;QAC7C,OAAOF;IACT;IAEA,qCAAqC;IACrC,MAAMG,UAAUL,OAAOM,MAAM,CAACJ;IAC9B,IAAIC,aAAaN,sBAAsBU,IAAI,EAAE;QAC3C,OAAOR,cAAcM;IACvB;IAEA,OAAOP,WAAWO;AACpB"}
1
+ {"version":3,"sources":["../../src/auxiliary-files.ts"],"sourcesContent":["import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';\nimport { bytesToHex, bytesToString } from '@metamask/utils';\n\nimport { decodeBase64 } from './base64';\n\n/**\n * Re-encodes an auxiliary file if needed depending on the requested file encoding.\n *\n * @param value - The base64 value stored for the auxiliary file.\n * @param encoding - The chosen encoding.\n * @returns The file encoded in the requested encoding.\n */\nexport async function encodeAuxiliaryFile(\n value: string,\n encoding: AuxiliaryFileEncoding,\n) {\n // Input is assumed to be the stored file in base64.\n if (encoding === AuxiliaryFileEncoding.Base64) {\n return value;\n }\n\n // TODO: Use @metamask/utils for this\n const decoded = await decodeBase64(value);\n if (encoding === AuxiliaryFileEncoding.Utf8) {\n return bytesToString(decoded);\n }\n\n return bytesToHex(decoded);\n}\n"],"names":["AuxiliaryFileEncoding","bytesToHex","bytesToString","decodeBase64","encodeAuxiliaryFile","value","encoding","Base64","decoded","Utf8"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,sBAAsB;AAC5D,SAASC,UAAU,EAAEC,aAAa,QAAQ,kBAAkB;AAE5D,SAASC,YAAY,QAAQ,WAAW;AAExC;;;;;;CAMC,GACD,OAAO,eAAeC,oBACpBC,KAAa,EACbC,QAA+B;IAE/B,oDAAoD;IACpD,IAAIA,aAAaN,sBAAsBO,MAAM,EAAE;QAC7C,OAAOF;IACT;IAEA,qCAAqC;IACrC,MAAMG,UAAU,MAAML,aAAaE;IACnC,IAAIC,aAAaN,sBAAsBS,IAAI,EAAE;QAC3C,OAAOP,cAAcM;IACvB;IAEA,OAAOP,WAAWO;AACpB"}
@@ -0,0 +1,36 @@
1
+ import { bytesToBase64 } from '@metamask/utils';
2
+ import { getBytes } from './bytes';
3
+ /**
4
+ * Provides fast, asynchronous base64 encoding.
5
+ *
6
+ * @param input - The input value, assumed to be coercable to bytes.
7
+ * @returns A base64 string.
8
+ */ export async function encodeBase64(input) {
9
+ const bytes = getBytes(input);
10
+ // In the browser, FileReader is much faster than bytesToBase64.
11
+ if ('FileReader' in globalThis) {
12
+ return await new Promise((resolve, reject)=>{
13
+ const reader = Object.assign(new FileReader(), {
14
+ onload: ()=>resolve(reader.result.replace('data:application/octet-stream;base64,', '')),
15
+ onerror: ()=>reject(reader.error)
16
+ });
17
+ reader.readAsDataURL(new File([
18
+ bytes
19
+ ], '', {
20
+ type: 'application/octet-stream'
21
+ }));
22
+ });
23
+ }
24
+ return bytesToBase64(bytes);
25
+ }
26
+ /**
27
+ * Provides fast, asynchronous base64 decoding.
28
+ *
29
+ * @param base64 - A base64 string.
30
+ * @returns A Uint8Array of bytes.
31
+ */ export async function decodeBase64(base64) {
32
+ const response = await fetch(`data:application/octet-stream;base64,${base64}`);
33
+ return new Uint8Array(await response.arrayBuffer());
34
+ }
35
+
36
+ //# sourceMappingURL=base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/base64.ts"],"sourcesContent":["import { bytesToBase64 } from '@metamask/utils';\n\nimport { getBytes } from './bytes';\nimport type { VirtualFile } from './virtual-file';\n\n/**\n * Provides fast, asynchronous base64 encoding.\n *\n * @param input - The input value, assumed to be coercable to bytes.\n * @returns A base64 string.\n */\nexport async function encodeBase64(input: Uint8Array | VirtualFile | string) {\n const bytes = getBytes(input);\n // In the browser, FileReader is much faster than bytesToBase64.\n if ('FileReader' in globalThis) {\n return await new Promise((resolve, reject) => {\n const reader = Object.assign(new FileReader(), {\n onload: () =>\n resolve(\n (reader.result as string).replace(\n 'data:application/octet-stream;base64,',\n '',\n ),\n ),\n onerror: () => reject(reader.error),\n });\n reader.readAsDataURL(\n new File([bytes], '', { type: 'application/octet-stream' }),\n );\n });\n }\n return bytesToBase64(bytes);\n}\n\n/**\n * Provides fast, asynchronous base64 decoding.\n *\n * @param base64 - A base64 string.\n * @returns A Uint8Array of bytes.\n */\nexport async function decodeBase64(base64: string) {\n const response = await fetch(\n `data:application/octet-stream;base64,${base64}`,\n );\n return new Uint8Array(await response.arrayBuffer());\n}\n"],"names":["bytesToBase64","getBytes","encodeBase64","input","bytes","globalThis","Promise","resolve","reject","reader","Object","assign","FileReader","onload","result","replace","onerror","error","readAsDataURL","File","type","decodeBase64","base64","response","fetch","Uint8Array","arrayBuffer"],"mappings":"AAAA,SAASA,aAAa,QAAQ,kBAAkB;AAEhD,SAASC,QAAQ,QAAQ,UAAU;AAGnC;;;;;CAKC,GACD,OAAO,eAAeC,aAAaC,KAAwC;IACzE,MAAMC,QAAQH,SAASE;IACvB,gEAAgE;IAChE,IAAI,gBAAgBE,YAAY;QAC9B,OAAO,MAAM,IAAIC,QAAQ,CAACC,SAASC;YACjC,MAAMC,SAASC,OAAOC,MAAM,CAAC,IAAIC,cAAc;gBAC7CC,QAAQ,IACNN,QACE,AAACE,OAAOK,MAAM,CAAYC,OAAO,CAC/B,yCACA;gBAGNC,SAAS,IAAMR,OAAOC,OAAOQ,KAAK;YACpC;YACAR,OAAOS,aAAa,CAClB,IAAIC,KAAK;gBAACf;aAAM,EAAE,IAAI;gBAAEgB,MAAM;YAA2B;QAE7D;IACF;IACA,OAAOpB,cAAcI;AACvB;AAEA;;;;;CAKC,GACD,OAAO,eAAeiB,aAAaC,MAAc;IAC/C,MAAMC,WAAW,MAAMC,MACrB,CAAC,qCAAqC,EAAEF,OAAO,CAAC;IAElD,OAAO,IAAIG,WAAW,MAAMF,SAASG,WAAW;AAClD"}
@@ -0,0 +1,18 @@
1
+ import { stringToBytes } from '@metamask/utils';
2
+ import { VirtualFile } from './virtual-file';
3
+ /**
4
+ * Convert a bytes-like input value to a Uint8Array.
5
+ *
6
+ * @param bytes - A bytes-like value.
7
+ * @returns The input value converted to a Uint8Array if necessary.
8
+ */ export function getBytes(bytes) {
9
+ // Unwrap VirtualFiles to extract the content
10
+ // The content is then either a string or Uint8Array
11
+ const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;
12
+ if (typeof unwrapped === 'string') {
13
+ return stringToBytes(unwrapped);
14
+ }
15
+ return unwrapped;
16
+ }
17
+
18
+ //# sourceMappingURL=bytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/bytes.ts"],"sourcesContent":["import { stringToBytes } from '@metamask/utils';\n\nimport { VirtualFile } from './virtual-file';\n\n/**\n * Convert a bytes-like input value to a Uint8Array.\n *\n * @param bytes - A bytes-like value.\n * @returns The input value converted to a Uint8Array if necessary.\n */\nexport function getBytes(bytes: VirtualFile | Uint8Array | string): Uint8Array {\n // Unwrap VirtualFiles to extract the content\n // The content is then either a string or Uint8Array\n const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;\n\n if (typeof unwrapped === 'string') {\n return stringToBytes(unwrapped);\n }\n\n return unwrapped;\n}\n"],"names":["stringToBytes","VirtualFile","getBytes","bytes","unwrapped","value"],"mappings":"AAAA,SAASA,aAAa,QAAQ,kBAAkB;AAEhD,SAASC,WAAW,QAAQ,iBAAiB;AAE7C;;;;;CAKC,GACD,OAAO,SAASC,SAASC,KAAwC;IAC/D,6CAA6C;IAC7C,oDAAoD;IACpD,MAAMC,YAAYD,iBAAiBF,cAAcE,MAAME,KAAK,GAAGF;IAE/D,IAAI,OAAOC,cAAc,UAAU;QACjC,OAAOJ,cAAcI;IACvB;IAEA,OAAOA;AACT"}
@@ -1,27 +1,13 @@
1
- import { assert, concatBytes, stringToBytes } from '@metamask/utils';
1
+ import { assert, concatBytes } from '@metamask/utils';
2
2
  import { sha256 } from '@noble/hashes/sha256';
3
- import { VirtualFile } from './virtual-file/VirtualFile';
4
- /**
5
- * Convert an input value to a Uint8Array for use in a checksum.
6
- *
7
- * @param bytes - A value to use for a checksum calculation.
8
- * @returns The input value converted to a Uint8Array if necessary.
9
- */ export function getChecksumBytes(bytes) {
10
- // Unwrap VirtualFiles to extract the content
11
- // The content is then either a string or Uint8Array
12
- const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;
13
- if (typeof unwrapped === 'string') {
14
- return stringToBytes(unwrapped);
15
- }
16
- return unwrapped;
17
- }
3
+ import { getBytes } from './bytes';
18
4
  /**
19
5
  * Calculates checksum for a single byte array.
20
6
  *
21
7
  * @param bytes - The byte array to calculate the checksum for.
22
8
  * @returns A single sha-256 checksum.
23
9
  */ export async function checksum(bytes) {
24
- const value = getChecksumBytes(bytes);
10
+ const value = getBytes(bytes);
25
11
  // Use crypto.subtle.digest whenever possible as it is faster.
26
12
  if ('crypto' in globalThis && typeof globalThis.crypto === 'object' && crypto.subtle?.digest) {
27
13
  return new Uint8Array(await crypto.subtle.digest('SHA-256', value));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/checksum.ts"],"sourcesContent":["import { assert, concatBytes, stringToBytes } from '@metamask/utils';\nimport { sha256 } from '@noble/hashes/sha256';\n\nimport { VirtualFile } from './virtual-file/VirtualFile';\n\n/**\n * Convert an input value to a Uint8Array for use in a checksum.\n *\n * @param bytes - A value to use for a checksum calculation.\n * @returns The input value converted to a Uint8Array if necessary.\n */\nexport function getChecksumBytes(\n bytes: VirtualFile | Uint8Array | string,\n): Uint8Array {\n // Unwrap VirtualFiles to extract the content\n // The content is then either a string or Uint8Array\n const unwrapped = bytes instanceof VirtualFile ? bytes.value : bytes;\n\n if (typeof unwrapped === 'string') {\n return stringToBytes(unwrapped);\n }\n\n return unwrapped;\n}\n\n/**\n * Calculates checksum for a single byte array.\n *\n * @param bytes - The byte array to calculate the checksum for.\n * @returns A single sha-256 checksum.\n */\nexport async function checksum(\n bytes: VirtualFile | Uint8Array | string,\n): Promise<Uint8Array> {\n const value = getChecksumBytes(bytes);\n // Use crypto.subtle.digest whenever possible as it is faster.\n if (\n 'crypto' in globalThis &&\n typeof globalThis.crypto === 'object' &&\n crypto.subtle?.digest\n ) {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', value));\n }\n return sha256(value);\n}\n\n/**\n * Calculates checksum over multiple files in a reproducible way.\n *\n * 1. Sort all the files by their paths.\n * 2. Calculate sha-256 checksum of each file separately.\n * 3. Concatenate all the checksums into one buffer and sha-256 that buffer.\n *\n * The sorting of paths is done using {@link https://tc39.es/ecma262/#sec-islessthan UTF-16 Code Units}.\n *\n * @param files - The files over which to calculate the checksum.\n * @returns A single sha-256 checksum.\n */\nexport async function checksumFiles(files: VirtualFile[]) {\n const checksums = await Promise.all(\n [...files]\n .sort((a, b) => {\n assert(a.path !== b.path, 'Tried to sort files with non-unique paths.');\n if (a.path < b.path) {\n return -1;\n }\n return 1;\n })\n .map(async (file) => checksum(file)),\n );\n\n return checksum(concatBytes(checksums));\n}\n"],"names":["assert","concatBytes","stringToBytes","sha256","VirtualFile","getChecksumBytes","bytes","unwrapped","value","checksum","globalThis","crypto","subtle","digest","Uint8Array","checksumFiles","files","checksums","Promise","all","sort","a","b","path","map","file"],"mappings":"AAAA,SAASA,MAAM,EAAEC,WAAW,EAAEC,aAAa,QAAQ,kBAAkB;AACrE,SAASC,MAAM,QAAQ,uBAAuB;AAE9C,SAASC,WAAW,QAAQ,6BAA6B;AAEzD;;;;;CAKC,GACD,OAAO,SAASC,iBACdC,KAAwC;IAExC,6CAA6C;IAC7C,oDAAoD;IACpD,MAAMC,YAAYD,iBAAiBF,cAAcE,MAAME,KAAK,GAAGF;IAE/D,IAAI,OAAOC,cAAc,UAAU;QACjC,OAAOL,cAAcK;IACvB;IAEA,OAAOA;AACT;AAEA;;;;;CAKC,GACD,OAAO,eAAeE,SACpBH,KAAwC;IAExC,MAAME,QAAQH,iBAAiBC;IAC/B,8DAA8D;IAC9D,IACE,YAAYI,cACZ,OAAOA,WAAWC,MAAM,KAAK,YAC7BA,OAAOC,MAAM,EAAEC,QACf;QACA,OAAO,IAAIC,WAAW,MAAMH,OAAOC,MAAM,CAACC,MAAM,CAAC,WAAWL;IAC9D;IACA,OAAOL,OAAOK;AAChB;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,eAAeO,cAAcC,KAAoB;IACtD,MAAMC,YAAY,MAAMC,QAAQC,GAAG,CACjC;WAAIH;KAAM,CACPI,IAAI,CAAC,CAACC,GAAGC;QACRtB,OAAOqB,EAAEE,IAAI,KAAKD,EAAEC,IAAI,EAAE;QAC1B,IAAIF,EAAEE,IAAI,GAAGD,EAAEC,IAAI,EAAE;YACnB,OAAO,CAAC;QACV;QACA,OAAO;IACT,GACCC,GAAG,CAAC,OAAOC,OAAShB,SAASgB;IAGlC,OAAOhB,SAASR,YAAYgB;AAC9B"}
1
+ {"version":3,"sources":["../../src/checksum.ts"],"sourcesContent":["import { assert, concatBytes } from '@metamask/utils';\nimport { sha256 } from '@noble/hashes/sha256';\n\nimport { getBytes } from './bytes';\nimport type { VirtualFile } from './virtual-file/VirtualFile';\n\n/**\n * Calculates checksum for a single byte array.\n *\n * @param bytes - The byte array to calculate the checksum for.\n * @returns A single sha-256 checksum.\n */\nexport async function checksum(\n bytes: VirtualFile | Uint8Array | string,\n): Promise<Uint8Array> {\n const value = getBytes(bytes);\n // Use crypto.subtle.digest whenever possible as it is faster.\n if (\n 'crypto' in globalThis &&\n typeof globalThis.crypto === 'object' &&\n crypto.subtle?.digest\n ) {\n return new Uint8Array(await crypto.subtle.digest('SHA-256', value));\n }\n return sha256(value);\n}\n\n/**\n * Calculates checksum over multiple files in a reproducible way.\n *\n * 1. Sort all the files by their paths.\n * 2. Calculate sha-256 checksum of each file separately.\n * 3. Concatenate all the checksums into one buffer and sha-256 that buffer.\n *\n * The sorting of paths is done using {@link https://tc39.es/ecma262/#sec-islessthan UTF-16 Code Units}.\n *\n * @param files - The files over which to calculate the checksum.\n * @returns A single sha-256 checksum.\n */\nexport async function checksumFiles(files: VirtualFile[]) {\n const checksums = await Promise.all(\n [...files]\n .sort((a, b) => {\n assert(a.path !== b.path, 'Tried to sort files with non-unique paths.');\n if (a.path < b.path) {\n return -1;\n }\n return 1;\n })\n .map(async (file) => checksum(file)),\n );\n\n return checksum(concatBytes(checksums));\n}\n"],"names":["assert","concatBytes","sha256","getBytes","checksum","bytes","value","globalThis","crypto","subtle","digest","Uint8Array","checksumFiles","files","checksums","Promise","all","sort","a","b","path","map","file"],"mappings":"AAAA,SAASA,MAAM,EAAEC,WAAW,QAAQ,kBAAkB;AACtD,SAASC,MAAM,QAAQ,uBAAuB;AAE9C,SAASC,QAAQ,QAAQ,UAAU;AAGnC;;;;;CAKC,GACD,OAAO,eAAeC,SACpBC,KAAwC;IAExC,MAAMC,QAAQH,SAASE;IACvB,8DAA8D;IAC9D,IACE,YAAYE,cACZ,OAAOA,WAAWC,MAAM,KAAK,YAC7BA,OAAOC,MAAM,EAAEC,QACf;QACA,OAAO,IAAIC,WAAW,MAAMH,OAAOC,MAAM,CAACC,MAAM,CAAC,WAAWJ;IAC9D;IACA,OAAOJ,OAAOI;AAChB;AAEA;;;;;;;;;;;CAWC,GACD,OAAO,eAAeM,cAAcC,KAAoB;IACtD,MAAMC,YAAY,MAAMC,QAAQC,GAAG,CACjC;WAAIH;KAAM,CACPI,IAAI,CAAC,CAACC,GAAGC;QACRnB,OAAOkB,EAAEE,IAAI,KAAKD,EAAEC,IAAI,EAAE;QAC1B,IAAIF,EAAEE,IAAI,GAAGD,EAAEC,IAAI,EAAE;YACnB,OAAO,CAAC;QACV;QACA,OAAO;IACT,GACCC,GAAG,CAAC,OAAOC,OAASlB,SAASkB;IAGlC,OAAOlB,SAASH,YAAYa;AAC9B"}
@@ -1,5 +1,7 @@
1
1
  export * from './array';
2
2
  export * from './auxiliary-files';
3
+ export * from './base64';
4
+ export * from './bytes';
3
5
  export * from './caveats';
4
6
  export * from './checksum';
5
7
  export * from './cronjob';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.browser.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './caveats';\nexport * from './checksum';\nexport * from './cronjob';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './errors';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest/index.browser';\nexport * from './namespace';\nexport * from './path';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file/index.browser';\n"],"names":[],"mappings":"AAAA,cAAc,UAAU;AACxB,cAAc,oBAAoB;AAClC,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,YAAY;AAC1B,cAAc,eAAe;AAC7B,cAAc,uBAAuB;AACrC,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,WAAW;AACzB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,iBAAiB;AAC/B,cAAc,YAAY;AAC1B,cAAc,2BAA2B;AACzC,cAAc,cAAc;AAC5B,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,UAAU;AACxB,cAAc,OAAO;AACrB,cAAc,eAAe;AAC7B,cAAc,aAAa;AAC3B,cAAc,+BAA+B"}
1
+ {"version":3,"sources":["../../src/index.browser.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './base64';\nexport * from './bytes';\nexport * from './caveats';\nexport * from './checksum';\nexport * from './cronjob';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './errors';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest/index.browser';\nexport * from './namespace';\nexport * from './path';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file/index.browser';\n"],"names":[],"mappings":"AAAA,cAAc,UAAU;AACxB,cAAc,oBAAoB;AAClC,cAAc,WAAW;AACzB,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,YAAY;AAC1B,cAAc,eAAe;AAC7B,cAAc,uBAAuB;AACrC,cAAc,YAAY;AAC1B,cAAc,WAAW;AACzB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,WAAW;AACzB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,iBAAiB;AAC/B,cAAc,YAAY;AAC1B,cAAc,2BAA2B;AACzC,cAAc,cAAc;AAC5B,cAAc,SAAS;AACvB,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,UAAU;AACxB,cAAc,OAAO;AACrB,cAAc,eAAe;AAC7B,cAAc,aAAa;AAC3B,cAAc,+BAA+B"}
package/dist/esm/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from './array';
2
2
  export * from './auxiliary-files';
3
+ export * from './base64';
4
+ export * from './bytes';
3
5
  export * from './caveats';
4
6
  export * from './cronjob';
5
7
  export * from './checksum';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './caveats';\nexport * from './cronjob';\nexport * from './checksum';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './eval';\nexport * from './errors';\nexport * from './fs';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest';\nexport * from './mock';\nexport * from './namespace';\nexport * from './npm';\nexport * from './path';\nexport * from './post-process';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file';\n"],"names":[],"mappings":"AAAA,cAAc,UAAU;AACxB,cAAc,oBAAoB;AAClC,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,cAAc,uBAAuB;AACrC,cAAc,YAAY;AAC1B,cAAc,SAAS;AACvB,cAAc,WAAW;AACzB,cAAc,OAAO;AACrB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,WAAW;AACzB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,iBAAiB;AAC/B,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,SAAS;AACvB,cAAc,cAAc;AAC5B,cAAc,QAAQ;AACtB,cAAc,SAAS;AACvB,cAAc,iBAAiB;AAC/B,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,UAAU;AACxB,cAAc,OAAO;AACrB,cAAc,eAAe;AAC7B,cAAc,aAAa;AAC3B,cAAc,iBAAiB"}
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './array';\nexport * from './auxiliary-files';\nexport * from './base64';\nexport * from './bytes';\nexport * from './caveats';\nexport * from './cronjob';\nexport * from './checksum';\nexport * from './deep-clone';\nexport * from './default-endowments';\nexport * from './entropy';\nexport * from './eval';\nexport * from './errors';\nexport * from './fs';\nexport * from './handlers';\nexport * from './handler-types';\nexport * from './iframe';\nexport * from './json';\nexport * from './json-rpc';\nexport * from './localization';\nexport * from './logging';\nexport * from './manifest';\nexport * from './mock';\nexport * from './namespace';\nexport * from './npm';\nexport * from './path';\nexport * from './post-process';\nexport * from './snaps';\nexport * from './strings';\nexport * from './structs';\nexport * from './types';\nexport * from './ui';\nexport * from './validation';\nexport * from './versions';\nexport * from './virtual-file';\n"],"names":[],"mappings":"AAAA,cAAc,UAAU;AACxB,cAAc,oBAAoB;AAClC,cAAc,WAAW;AACzB,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,eAAe;AAC7B,cAAc,uBAAuB;AACrC,cAAc,YAAY;AAC1B,cAAc,SAAS;AACvB,cAAc,WAAW;AACzB,cAAc,OAAO;AACrB,cAAc,aAAa;AAC3B,cAAc,kBAAkB;AAChC,cAAc,WAAW;AACzB,cAAc,SAAS;AACvB,cAAc,aAAa;AAC3B,cAAc,iBAAiB;AAC/B,cAAc,YAAY;AAC1B,cAAc,aAAa;AAC3B,cAAc,SAAS;AACvB,cAAc,cAAc;AAC5B,cAAc,QAAQ;AACtB,cAAc,SAAS;AACvB,cAAc,iBAAiB;AAC/B,cAAc,UAAU;AACxB,cAAc,YAAY;AAC1B,cAAc,YAAY;AAC1B,cAAc,UAAU;AACxB,cAAc,OAAO;AACrB,cAAc,eAAe;AAC7B,cAAc,aAAa;AAC3B,cAAc,iBAAiB"}
@@ -30,6 +30,7 @@ export class VirtualFile {
30
30
  } else if (this.value instanceof Uint8Array && encoding === 'hex') {
31
31
  return bytesToHex(this.value);
32
32
  } else if (this.value instanceof Uint8Array && encoding === 'base64') {
33
+ // For large files, this is quite slow, instead use `encodeBase64()`
33
34
  // TODO: Use @metamask/utils for this
34
35
  return base64.encode(this.value);
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/virtual-file/VirtualFile.ts"],"sourcesContent":["// TODO(ritave): Move into separate package @metamask/vfile / @metamask/utils + @metamask/to-vfile when passes code review\n// TODO(ritave): Streaming vfile contents similar to vinyl maybe?\n// TODO(ritave): Move fixing manifest in cli and bundler plugins to write messages to vfile\n// similar to unified instead of throwing \"ProgrammaticallyFixableErrors\".\n//\n// Using https://github.com/vfile/vfile would be helpful, but they only support ESM and we need to support CommonJS.\n// https://github.com/gulpjs/vinyl is also good, but they normalize paths, which we can't do, because\n// we're calculating checksums based on original path.\nimport { assert, bytesToHex } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\nimport { deepClone } from '../deep-clone';\n\n/**\n * This map registers the type of the {@link VirtualFile.data} key of a {@link VirtualFile}.\n *\n * This type can be augmented to register custom `data` types.\n *\n * @example\n * declare module '@metamask/snaps-utils' {\n * interface DataMap {\n * // `file.data.name` is typed as `string`\n * name: string\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-empty-interface\nexport interface DataMap {}\n\nexport type Value = string | Uint8Array;\nexport type Compatible<Result = unknown> =\n | string\n | Uint8Array\n | Options<Result>;\nexport type Data = Record<string, unknown> & Partial<DataMap>;\nexport type Options<Result = unknown> = {\n value: Value;\n path?: string;\n data?: Data;\n result?: Result;\n};\n\nexport class VirtualFile<Result = unknown> {\n constructor(value?: Compatible<Result>) {\n let options: Options | undefined;\n if (typeof value === 'string' || value instanceof Uint8Array) {\n options = { value };\n } else {\n options = value;\n }\n\n this.value = options?.value ?? '';\n // This situations happens when there's no .result used,\n // we expect the file to have default generic in that situation:\n // VirtualFile<unknown> which will handle undefined properly\n //\n // While not 100% type safe, it'll be way less frustrating to work with.\n // The alternative would be to have VirtualFile.result be Result | undefined\n // and that would result in needing to branch out and check in all situations.\n //\n // In short, optimizing for most common use case.\n this.result = options?.result ?? (undefined as any);\n this.data = options?.data ?? {};\n this.path = options?.path ?? '/';\n }\n\n value: Value;\n\n result: Result;\n\n data: Data;\n\n path: string;\n\n toString(encoding?: string) {\n if (typeof this.value === 'string') {\n assert(encoding === undefined, 'Tried to encode string.');\n return this.value;\n } else if (this.value instanceof Uint8Array && encoding === 'hex') {\n return bytesToHex(this.value);\n } else if (this.value instanceof Uint8Array && encoding === 'base64') {\n // TODO: Use @metamask/utils for this\n return base64.encode(this.value);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(this.value);\n }\n\n clone() {\n const vfile = new VirtualFile<Result>();\n if (typeof this.value === 'string') {\n vfile.value = this.value;\n } else {\n // deep-clone doesn't clone Buffer properly, even if it's a sub-class of Uint8Array\n vfile.value = this.value.slice(0);\n }\n vfile.result = deepClone(this.result);\n vfile.data = deepClone(this.data);\n vfile.path = this.path;\n return vfile;\n }\n}\n"],"names":["assert","bytesToHex","base64","deepClone","VirtualFile","toString","encoding","value","undefined","Uint8Array","encode","decoder","TextDecoder","decode","clone","vfile","slice","result","data","path","constructor","options"],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;;;;;;;;;;;;;;AACtD,SAASA,MAAM,EAAEC,UAAU,QAAQ,kBAAkB;AACrD,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,SAAS,QAAQ,gBAAgB;AA+B1C,OAAO,MAAMC;IAgCXC,SAASC,QAAiB,EAAE;QAC1B,IAAI,OAAO,IAAI,CAACC,KAAK,KAAK,UAAU;YAClCP,OAAOM,aAAaE,WAAW;YAC/B,OAAO,IAAI,CAACD,KAAK;QACnB,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYE,cAAcH,aAAa,OAAO;YACjE,OAAOL,WAAW,IAAI,CAACM,KAAK;QAC9B,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYE,cAAcH,aAAa,UAAU;YACpE,qCAAqC;YACrC,OAAOJ,OAAOQ,MAAM,CAAC,IAAI,CAACH,KAAK;QACjC;QACA,MAAMI,UAAU,IAAIC,YAAYN;QAChC,OAAOK,QAAQE,MAAM,CAAC,IAAI,CAACN,KAAK;IAClC;IAEAO,QAAQ;QACN,MAAMC,QAAQ,IAAIX;QAClB,IAAI,OAAO,IAAI,CAACG,KAAK,KAAK,UAAU;YAClCQ,MAAMR,KAAK,GAAG,IAAI,CAACA,KAAK;QAC1B,OAAO;YACL,mFAAmF;YACnFQ,MAAMR,KAAK,GAAG,IAAI,CAACA,KAAK,CAACS,KAAK,CAAC;QACjC;QACAD,MAAME,MAAM,GAAGd,UAAU,IAAI,CAACc,MAAM;QACpCF,MAAMG,IAAI,GAAGf,UAAU,IAAI,CAACe,IAAI;QAChCH,MAAMI,IAAI,GAAG,IAAI,CAACA,IAAI;QACtB,OAAOJ;IACT;IAzDAK,YAAYb,KAA0B,CAAE;QAuBxCA,uBAAAA,SAAAA,KAAAA;QAEAU,uBAAAA,UAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QA5BE,IAAIE;QACJ,IAAI,OAAOd,UAAU,YAAYA,iBAAiBE,YAAY;YAC5DY,UAAU;gBAAEd;YAAM;QACpB,OAAO;YACLc,UAAUd;QACZ;QAEA,IAAI,CAACA,KAAK,GAAGc,SAASd,SAAS;QAC/B,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAACU,MAAM,GAAGI,SAASJ,UAAWT;QAClC,IAAI,CAACU,IAAI,GAAGG,SAASH,QAAQ,CAAC;QAC9B,IAAI,CAACC,IAAI,GAAGE,SAASF,QAAQ;IAC/B;AAqCF"}
1
+ {"version":3,"sources":["../../../src/virtual-file/VirtualFile.ts"],"sourcesContent":["// TODO(ritave): Move into separate package @metamask/vfile / @metamask/utils + @metamask/to-vfile when passes code review\n// TODO(ritave): Streaming vfile contents similar to vinyl maybe?\n// TODO(ritave): Move fixing manifest in cli and bundler plugins to write messages to vfile\n// similar to unified instead of throwing \"ProgrammaticallyFixableErrors\".\n//\n// Using https://github.com/vfile/vfile would be helpful, but they only support ESM and we need to support CommonJS.\n// https://github.com/gulpjs/vinyl is also good, but they normalize paths, which we can't do, because\n// we're calculating checksums based on original path.\nimport { assert, bytesToHex } from '@metamask/utils';\nimport { base64 } from '@scure/base';\n\nimport { deepClone } from '../deep-clone';\n\n/**\n * This map registers the type of the {@link VirtualFile.data} key of a {@link VirtualFile}.\n *\n * This type can be augmented to register custom `data` types.\n *\n * @example\n * declare module '@metamask/snaps-utils' {\n * interface DataMap {\n * // `file.data.name` is typed as `string`\n * name: string\n * }\n * }\n */\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-empty-interface\nexport interface DataMap {}\n\nexport type Value = string | Uint8Array;\nexport type Compatible<Result = unknown> =\n | string\n | Uint8Array\n | Options<Result>;\nexport type Data = Record<string, unknown> & Partial<DataMap>;\nexport type Options<Result = unknown> = {\n value: Value;\n path?: string;\n data?: Data;\n result?: Result;\n};\n\nexport class VirtualFile<Result = unknown> {\n constructor(value?: Compatible<Result>) {\n let options: Options | undefined;\n if (typeof value === 'string' || value instanceof Uint8Array) {\n options = { value };\n } else {\n options = value;\n }\n\n this.value = options?.value ?? '';\n // This situations happens when there's no .result used,\n // we expect the file to have default generic in that situation:\n // VirtualFile<unknown> which will handle undefined properly\n //\n // While not 100% type safe, it'll be way less frustrating to work with.\n // The alternative would be to have VirtualFile.result be Result | undefined\n // and that would result in needing to branch out and check in all situations.\n //\n // In short, optimizing for most common use case.\n this.result = options?.result ?? (undefined as any);\n this.data = options?.data ?? {};\n this.path = options?.path ?? '/';\n }\n\n value: Value;\n\n result: Result;\n\n data: Data;\n\n path: string;\n\n toString(encoding?: string) {\n if (typeof this.value === 'string') {\n assert(encoding === undefined, 'Tried to encode string.');\n return this.value;\n } else if (this.value instanceof Uint8Array && encoding === 'hex') {\n return bytesToHex(this.value);\n } else if (this.value instanceof Uint8Array && encoding === 'base64') {\n // For large files, this is quite slow, instead use `encodeBase64()`\n // TODO: Use @metamask/utils for this\n return base64.encode(this.value);\n }\n const decoder = new TextDecoder(encoding);\n return decoder.decode(this.value);\n }\n\n clone() {\n const vfile = new VirtualFile<Result>();\n if (typeof this.value === 'string') {\n vfile.value = this.value;\n } else {\n // deep-clone doesn't clone Buffer properly, even if it's a sub-class of Uint8Array\n vfile.value = this.value.slice(0);\n }\n vfile.result = deepClone(this.result);\n vfile.data = deepClone(this.data);\n vfile.path = this.path;\n return vfile;\n }\n}\n"],"names":["assert","bytesToHex","base64","deepClone","VirtualFile","toString","encoding","value","undefined","Uint8Array","encode","decoder","TextDecoder","decode","clone","vfile","slice","result","data","path","constructor","options"],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;;;;;;;;;;;;;;AACtD,SAASA,MAAM,EAAEC,UAAU,QAAQ,kBAAkB;AACrD,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,SAAS,QAAQ,gBAAgB;AA+B1C,OAAO,MAAMC;IAgCXC,SAASC,QAAiB,EAAE;QAC1B,IAAI,OAAO,IAAI,CAACC,KAAK,KAAK,UAAU;YAClCP,OAAOM,aAAaE,WAAW;YAC/B,OAAO,IAAI,CAACD,KAAK;QACnB,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYE,cAAcH,aAAa,OAAO;YACjE,OAAOL,WAAW,IAAI,CAACM,KAAK;QAC9B,OAAO,IAAI,IAAI,CAACA,KAAK,YAAYE,cAAcH,aAAa,UAAU;YACpE,oEAAoE;YACpE,qCAAqC;YACrC,OAAOJ,OAAOQ,MAAM,CAAC,IAAI,CAACH,KAAK;QACjC;QACA,MAAMI,UAAU,IAAIC,YAAYN;QAChC,OAAOK,QAAQE,MAAM,CAAC,IAAI,CAACN,KAAK;IAClC;IAEAO,QAAQ;QACN,MAAMC,QAAQ,IAAIX;QAClB,IAAI,OAAO,IAAI,CAACG,KAAK,KAAK,UAAU;YAClCQ,MAAMR,KAAK,GAAG,IAAI,CAACA,KAAK;QAC1B,OAAO;YACL,mFAAmF;YACnFQ,MAAMR,KAAK,GAAG,IAAI,CAACA,KAAK,CAACS,KAAK,CAAC;QACjC;QACAD,MAAME,MAAM,GAAGd,UAAU,IAAI,CAACc,MAAM;QACpCF,MAAMG,IAAI,GAAGf,UAAU,IAAI,CAACe,IAAI;QAChCH,MAAMI,IAAI,GAAG,IAAI,CAACA,IAAI;QACtB,OAAOJ;IACT;IA1DAK,YAAYb,KAA0B,CAAE;QAuBxCA,uBAAAA,SAAAA,KAAAA;QAEAU,uBAAAA,UAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QAEAC,uBAAAA,QAAAA,KAAAA;QA5BE,IAAIE;QACJ,IAAI,OAAOd,UAAU,YAAYA,iBAAiBE,YAAY;YAC5DY,UAAU;gBAAEd;YAAM;QACpB,OAAO;YACLc,UAAUd;QACZ;QAEA,IAAI,CAACA,KAAK,GAAGc,SAASd,SAAS;QAC/B,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAACU,MAAM,GAAGI,SAASJ,UAAWT;QAClC,IAAI,CAACU,IAAI,GAAGG,SAASH,QAAQ,CAAC;QAC9B,IAAI,CAACC,IAAI,GAAGE,SAASF,QAAQ;IAC/B;AAsCF"}
@@ -6,4 +6,4 @@ import { AuxiliaryFileEncoding } from '@metamask/snaps-sdk';
6
6
  * @param encoding - The chosen encoding.
7
7
  * @returns The file encoded in the requested encoding.
8
8
  */
9
- export declare function encodeAuxiliaryFile(value: string, encoding: AuxiliaryFileEncoding): string;
9
+ export declare function encodeAuxiliaryFile(value: string, encoding: AuxiliaryFileEncoding): Promise<string>;
@@ -0,0 +1,15 @@
1
+ import type { VirtualFile } from './virtual-file';
2
+ /**
3
+ * Provides fast, asynchronous base64 encoding.
4
+ *
5
+ * @param input - The input value, assumed to be coercable to bytes.
6
+ * @returns A base64 string.
7
+ */
8
+ export declare function encodeBase64(input: Uint8Array | VirtualFile | string): Promise<unknown>;
9
+ /**
10
+ * Provides fast, asynchronous base64 decoding.
11
+ *
12
+ * @param base64 - A base64 string.
13
+ * @returns A Uint8Array of bytes.
14
+ */
15
+ export declare function decodeBase64(base64: string): Promise<Uint8Array>;
@@ -0,0 +1,8 @@
1
+ import { VirtualFile } from './virtual-file';
2
+ /**
3
+ * Convert a bytes-like input value to a Uint8Array.
4
+ *
5
+ * @param bytes - A bytes-like value.
6
+ * @returns The input value converted to a Uint8Array if necessary.
7
+ */
8
+ export declare function getBytes(bytes: VirtualFile | Uint8Array | string): Uint8Array;
@@ -1,11 +1,4 @@
1
- import { VirtualFile } from './virtual-file/VirtualFile';
2
- /**
3
- * Convert an input value to a Uint8Array for use in a checksum.
4
- *
5
- * @param bytes - A value to use for a checksum calculation.
6
- * @returns The input value converted to a Uint8Array if necessary.
7
- */
8
- export declare function getChecksumBytes(bytes: VirtualFile | Uint8Array | string): Uint8Array;
1
+ import type { VirtualFile } from './virtual-file/VirtualFile';
9
2
  /**
10
3
  * Calculates checksum for a single byte array.
11
4
  *
@@ -1,5 +1,7 @@
1
1
  export * from './array';
2
2
  export * from './auxiliary-files';
3
+ export * from './base64';
4
+ export * from './bytes';
3
5
  export * from './caveats';
4
6
  export * from './checksum';
5
7
  export * from './cronjob';
@@ -1,5 +1,7 @@
1
1
  export * from './array';
2
2
  export * from './auxiliary-files';
3
+ export * from './base64';
4
+ export * from './bytes';
3
5
  export * from './caveats';
4
6
  export * from './cronjob';
5
7
  export * from './checksum';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-utils",
3
- "version": "5.0.0",
3
+ "version": "5.0.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/MetaMask/snaps.git"
@@ -67,12 +67,12 @@
67
67
  "dependencies": {
68
68
  "@babel/core": "^7.23.2",
69
69
  "@babel/types": "^7.23.0",
70
- "@metamask/base-controller": "^3.2.0",
70
+ "@metamask/base-controller": "^4.0.0",
71
71
  "@metamask/key-tree": "^9.0.0",
72
- "@metamask/permission-controller": "^5.0.1",
72
+ "@metamask/permission-controller": "^6.0.0",
73
73
  "@metamask/rpc-errors": "^6.1.0",
74
- "@metamask/snaps-registry": "^2.1.0",
75
- "@metamask/snaps-sdk": "^1.2.0",
74
+ "@metamask/snaps-registry": "^2.1.1",
75
+ "@metamask/snaps-sdk": "^1.3.0",
76
76
  "@metamask/utils": "^8.2.1",
77
77
  "@noble/hashes": "^1.3.1",
78
78
  "@scure/base": "^1.1.1",