@metamask/snaps-utils 9.3.0 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/dist/account.cjs +53 -0
  3. package/dist/account.cjs.map +1 -1
  4. package/dist/account.d.cts +26 -1
  5. package/dist/account.d.cts.map +1 -1
  6. package/dist/account.d.mts +26 -1
  7. package/dist/account.d.mts.map +1 -1
  8. package/dist/account.mjs +49 -1
  9. package/dist/account.mjs.map +1 -1
  10. package/dist/cronjob.cjs +16 -15
  11. package/dist/cronjob.cjs.map +1 -1
  12. package/dist/cronjob.d.cts +27 -36
  13. package/dist/cronjob.d.cts.map +1 -1
  14. package/dist/cronjob.d.mts +27 -36
  15. package/dist/cronjob.d.mts.map +1 -1
  16. package/dist/cronjob.mjs +16 -14
  17. package/dist/cronjob.mjs.map +1 -1
  18. package/dist/errors.cjs +22 -24
  19. package/dist/errors.cjs.map +1 -1
  20. package/dist/errors.d.cts.map +1 -1
  21. package/dist/errors.d.mts.map +1 -1
  22. package/dist/errors.mjs +22 -24
  23. package/dist/errors.mjs.map +1 -1
  24. package/dist/eval-worker.cjs +38 -11
  25. package/dist/eval-worker.cjs.map +1 -1
  26. package/dist/eval-worker.d.cts.map +1 -1
  27. package/dist/eval-worker.d.mts.map +1 -1
  28. package/dist/eval-worker.mjs +38 -11
  29. package/dist/eval-worker.mjs.map +1 -1
  30. package/dist/eval.cjs +7 -0
  31. package/dist/eval.cjs.map +1 -1
  32. package/dist/eval.d.cts +7 -0
  33. package/dist/eval.d.cts.map +1 -1
  34. package/dist/eval.d.mts +7 -0
  35. package/dist/eval.d.mts.map +1 -1
  36. package/dist/eval.mjs +7 -0
  37. package/dist/eval.mjs.map +1 -1
  38. package/dist/fs.cjs +51 -6
  39. package/dist/fs.cjs.map +1 -1
  40. package/dist/fs.d.cts +16 -4
  41. package/dist/fs.d.cts.map +1 -1
  42. package/dist/fs.d.mts +16 -4
  43. package/dist/fs.d.mts.map +1 -1
  44. package/dist/fs.mjs +49 -5
  45. package/dist/fs.mjs.map +1 -1
  46. package/dist/handlers/home-page.d.cts +3 -3
  47. package/dist/handlers/home-page.d.mts +3 -3
  48. package/dist/handlers/settings-page.d.cts +1 -1
  49. package/dist/handlers/settings-page.d.mts +1 -1
  50. package/dist/handlers/signature.d.cts +1 -1
  51. package/dist/handlers/signature.d.mts +1 -1
  52. package/dist/handlers/transaction.d.cts +3 -3
  53. package/dist/handlers/transaction.d.mts +3 -3
  54. package/dist/index.cjs +1 -0
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.cts +1 -1
  57. package/dist/index.d.cts.map +1 -1
  58. package/dist/index.d.mts +1 -1
  59. package/dist/index.d.mts.map +1 -1
  60. package/dist/index.mjs +1 -0
  61. package/dist/index.mjs.map +1 -1
  62. package/dist/manifest/manifest.cjs +36 -4
  63. package/dist/manifest/manifest.cjs.map +1 -1
  64. package/dist/manifest/manifest.d.cts +40 -7
  65. package/dist/manifest/manifest.d.cts.map +1 -1
  66. package/dist/manifest/manifest.d.mts +40 -7
  67. package/dist/manifest/manifest.d.mts.map +1 -1
  68. package/dist/manifest/manifest.mjs +13 -4
  69. package/dist/manifest/manifest.mjs.map +1 -1
  70. package/dist/manifest/validator-types.cjs.map +1 -1
  71. package/dist/manifest/validator-types.d.cts +18 -1
  72. package/dist/manifest/validator-types.d.cts.map +1 -1
  73. package/dist/manifest/validator-types.d.mts +18 -1
  74. package/dist/manifest/validator-types.d.mts.map +1 -1
  75. package/dist/manifest/validator-types.mjs.map +1 -1
  76. package/dist/manifest/validator.cjs +21 -21
  77. package/dist/manifest/validator.cjs.map +1 -1
  78. package/dist/manifest/validator.d.cts +4 -2
  79. package/dist/manifest/validator.d.cts.map +1 -1
  80. package/dist/manifest/validator.d.mts +4 -2
  81. package/dist/manifest/validator.d.mts.map +1 -1
  82. package/dist/manifest/validator.mjs +21 -21
  83. package/dist/manifest/validator.mjs.map +1 -1
  84. package/dist/manifest/validators/index.cjs +2 -0
  85. package/dist/manifest/validators/index.cjs.map +1 -1
  86. package/dist/manifest/validators/index.d.cts +2 -0
  87. package/dist/manifest/validators/index.d.cts.map +1 -1
  88. package/dist/manifest/validators/index.d.mts +2 -0
  89. package/dist/manifest/validators/index.d.mts.map +1 -1
  90. package/dist/manifest/validators/index.mjs +2 -0
  91. package/dist/manifest/validators/index.mjs.map +1 -1
  92. package/dist/manifest/validators/production-platform-version.cjs +47 -0
  93. package/dist/manifest/validators/production-platform-version.cjs.map +1 -0
  94. package/dist/manifest/validators/production-platform-version.d.cts +7 -0
  95. package/dist/manifest/validators/production-platform-version.d.cts.map +1 -0
  96. package/dist/manifest/validators/production-platform-version.d.mts +7 -0
  97. package/dist/manifest/validators/production-platform-version.d.mts.map +1 -0
  98. package/dist/manifest/validators/production-platform-version.mjs +44 -0
  99. package/dist/manifest/validators/production-platform-version.mjs.map +1 -0
  100. package/dist/manifest/validators/unused-exports.cjs +53 -0
  101. package/dist/manifest/validators/unused-exports.cjs.map +1 -0
  102. package/dist/manifest/validators/unused-exports.d.cts +7 -0
  103. package/dist/manifest/validators/unused-exports.d.cts.map +1 -0
  104. package/dist/manifest/validators/unused-exports.d.mts +7 -0
  105. package/dist/manifest/validators/unused-exports.d.mts.map +1 -0
  106. package/dist/manifest/validators/unused-exports.mjs +50 -0
  107. package/dist/manifest/validators/unused-exports.mjs.map +1 -0
  108. package/dist/time.cjs +15 -1
  109. package/dist/time.cjs.map +1 -1
  110. package/dist/time.d.cts +7 -0
  111. package/dist/time.d.cts.map +1 -1
  112. package/dist/time.d.mts +7 -0
  113. package/dist/time.d.mts.map +1 -1
  114. package/dist/time.mjs +13 -0
  115. package/dist/time.mjs.map +1 -1
  116. package/dist/virtual-file/VirtualFile.cjs +4 -0
  117. package/dist/virtual-file/VirtualFile.cjs.map +1 -1
  118. package/dist/virtual-file/VirtualFile.mjs +4 -0
  119. package/dist/virtual-file/VirtualFile.mjs.map +1 -1
  120. package/package.json +8 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-exports.d.cts","sourceRoot":"","sources":["../../../src/manifest/validators/unused-exports.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA2B;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,aAwE3B,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ValidatorMeta } from "../validator-types.mjs";
2
+ /**
3
+ * Check if the Snap exports handlers that are not requested in the manifest, or
4
+ * if the Snap requests permissions for handlers that are not exported.
5
+ */
6
+ export declare const unusedExports: ValidatorMeta;
7
+ //# sourceMappingURL=unused-exports.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-exports.d.mts","sourceRoot":"","sources":["../../../src/manifest/validators/unused-exports.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA2B;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,aAwE3B,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Check if the Snap exports handlers that are not requested in the manifest, or
3
+ * if the Snap requests permissions for handlers that are not exported.
4
+ */
5
+ export const unusedExports = {
6
+ severity: 'warning',
7
+ semanticCheck(files, context) {
8
+ const { handlerEndowments, exports } = context.options ?? {};
9
+ // The handler endowments or exports must be provided for this check to be
10
+ // performed.
11
+ if (!handlerEndowments || !exports) {
12
+ return;
13
+ }
14
+ const unusedHandlers = Object.entries(handlerEndowments)
15
+ .filter(([handler, endowment]) => {
16
+ if (endowment === null) {
17
+ return false;
18
+ }
19
+ return (exports.includes(handler) &&
20
+ !files.manifest.result.initialPermissions[endowment]);
21
+ })
22
+ .map(([handler, endowment]) => `${handler} (${endowment})`);
23
+ const unusedEndowments = Object.entries(handlerEndowments).filter(([handler, endowment]) => {
24
+ if (endowment === null) {
25
+ return false;
26
+ }
27
+ return (files.manifest.result.initialPermissions[endowment] && !exports.includes(handler));
28
+ });
29
+ if (unusedHandlers.length > 0) {
30
+ // We don't specify a fix function here, because:
31
+ // 1. Removing the export from the Snap bundle is complicated, as it
32
+ // requires AST manipulation.
33
+ // 2. Adding the permission to the manifest is not always possible, as it
34
+ // may require additional configuration in the manifest.
35
+ context.report(`The Snap exports the following handlers, but does not request permission for them: ${unusedHandlers.join(', ')}.`);
36
+ }
37
+ if (unusedEndowments.length > 0) {
38
+ const formattedEndowments = unusedEndowments
39
+ .map(([handler, endowment]) => `${handler} (${endowment})`)
40
+ .join(', ');
41
+ context.report(`The Snap requests permission for the following handlers, but does not export them: ${formattedEndowments}.`, ({ manifest }) => {
42
+ unusedEndowments.forEach(([, endowment]) => {
43
+ delete manifest.initialPermissions[endowment];
44
+ });
45
+ return { manifest };
46
+ });
47
+ }
48
+ },
49
+ };
50
+ //# sourceMappingURL=unused-exports.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unused-exports.mjs","sourceRoot":"","sources":["../../../src/manifest/validators/unused-exports.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,QAAQ,EAAE,SAAS;IACnB,aAAa,CAAC,KAAK,EAAE,OAAO;QAC1B,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAE7D,0EAA0E;QAC1E,aAAa;QACb,IAAI,CAAC,iBAAiB,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC;aACrD,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE;YAC/B,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACzB,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CACvC,SAAqC,CACtC,CACF,CAAC;QACJ,CAAC,CAAC;aACD,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,KAAK,SAAS,GAAG,CAAC,CAAC;QAE9D,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAC/D,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE;YACvB,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,OAAO,KAAK,CAAC;YACf,CAAC;YAED,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CACtC,SAAqC,CACtC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAChC,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,iDAAiD;YACjD,oEAAoE;YACpE,gCAAgC;YAChC,yEAAyE;YACzE,2DAA2D;YAC3D,OAAO,CAAC,MAAM,CACZ,sFAAsF,cAAc,CAAC,IAAI,CACvG,IAAI,CACL,GAAG,CACL,CAAC;QACJ,CAAC;QAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,mBAAmB,GAAG,gBAAgB;iBACzC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,KAAK,SAAS,GAAG,CAAC;iBAC1D,IAAI,CAAC,IAAI,CAAC,CAAC;YAEd,OAAO,CAAC,MAAM,CACZ,sFAAsF,mBAAmB,GAAG,EAC5G,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACf,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE;oBACzC,OAAO,QAAQ,CAAC,kBAAkB,CAChC,SAAqC,CACtC,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,OAAO,EAAE,QAAQ,EAAE,CAAC;YACtB,CAAC,CACF,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import type { InitialPermissions } from '@metamask/snaps-sdk';\n\nimport type { ValidatorMeta } from '../validator-types';\n\n/**\n * Check if the Snap exports handlers that are not requested in the manifest, or\n * if the Snap requests permissions for handlers that are not exported.\n */\nexport const unusedExports: ValidatorMeta = {\n severity: 'warning',\n semanticCheck(files, context) {\n const { handlerEndowments, exports } = context.options ?? {};\n\n // The handler endowments or exports must be provided for this check to be\n // performed.\n if (!handlerEndowments || !exports) {\n return;\n }\n\n const unusedHandlers = Object.entries(handlerEndowments)\n .filter(([handler, endowment]) => {\n if (endowment === null) {\n return false;\n }\n\n return (\n exports.includes(handler) &&\n !files.manifest.result.initialPermissions[\n endowment as keyof InitialPermissions\n ]\n );\n })\n .map(([handler, endowment]) => `${handler} (${endowment})`);\n\n const unusedEndowments = Object.entries(handlerEndowments).filter(\n ([handler, endowment]) => {\n if (endowment === null) {\n return false;\n }\n\n return (\n files.manifest.result.initialPermissions[\n endowment as keyof InitialPermissions\n ] && !exports.includes(handler)\n );\n },\n );\n\n if (unusedHandlers.length > 0) {\n // We don't specify a fix function here, because:\n // 1. Removing the export from the Snap bundle is complicated, as it\n // requires AST manipulation.\n // 2. Adding the permission to the manifest is not always possible, as it\n // may require additional configuration in the manifest.\n context.report(\n `The Snap exports the following handlers, but does not request permission for them: ${unusedHandlers.join(\n ', ',\n )}.`,\n );\n }\n\n if (unusedEndowments.length > 0) {\n const formattedEndowments = unusedEndowments\n .map(([handler, endowment]) => `${handler} (${endowment})`)\n .join(', ');\n\n context.report(\n `The Snap requests permission for the following handlers, but does not export them: ${formattedEndowments}.`,\n ({ manifest }) => {\n unusedEndowments.forEach(([, endowment]) => {\n delete manifest.initialPermissions[\n endowment as keyof InitialPermissions\n ];\n });\n\n return { manifest };\n },\n );\n }\n },\n};\n"]}
package/dist/time.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ISO8601DateStruct = exports.ISO8601DurationStruct = void 0;
3
+ exports.toCensoredISO8601String = exports.ISO8601DateStruct = exports.ISO8601DurationStruct = void 0;
4
4
  const superstruct_1 = require("@metamask/superstruct");
5
5
  const luxon_1 = require("luxon");
6
6
  /**
@@ -31,4 +31,18 @@ exports.ISO8601DateStruct = (0, superstruct_1.refine)((0, superstruct_1.string)(
31
31
  }
32
32
  return true;
33
33
  });
34
+ /**
35
+ * Remove millisecond precision from an ISO 8601 string.
36
+ *
37
+ * @param value - A valid ISO 8601 date.
38
+ * @returns A valid ISO 8601 date with millisecond precision removed.
39
+ */
40
+ function toCensoredISO8601String(value) {
41
+ const date = luxon_1.DateTime.fromISO(value, { setZone: true });
42
+ // Make sure any millisecond precision is removed.
43
+ return date.startOf('second').toISO({
44
+ suppressMilliseconds: true,
45
+ });
46
+ }
47
+ exports.toCensoredISO8601String = toCensoredISO8601String;
34
48
  //# sourceMappingURL=time.cjs.map
package/dist/time.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.cjs","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":";;;AAAA,uDAAuD;AACvD,iCAA2C;AAE3C;;GAEG;AACU,QAAA,qBAAqB,GAAG,IAAA,oBAAM,EACzC,IAAA,oBAAM,GAAE,EACR,mBAAmB,EACnB,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,cAAc,GAAG,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,+BAA+B,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;GAEG;AACU,QAAA,iBAAiB,GAAG,IAAA,oBAAM,EAAC,IAAA,oBAAM,GAAE,EAAE,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IAC3E,MAAM,UAAU,GAAG,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,+EAA+E;QAC/E,OAAO,8CAA8C,CAAC;IACxD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC","sourcesContent":["import { refine, string } from '@metamask/superstruct';\nimport { DateTime, Duration } from 'luxon';\n\n/**\n * Refines a string as an ISO 8601 duration.\n */\nexport const ISO8601DurationStruct = refine(\n string(),\n 'ISO 8601 duration',\n (value) => {\n const parsedDuration = Duration.fromISO(value);\n if (!parsedDuration.isValid) {\n return 'Not a valid ISO 8601 duration';\n }\n return true;\n },\n);\n\n/**\n * Regex to match the offset part of an ISO 8601 date.\n */\nconst offsetRegex = /Z|([+-]\\d{2}:?\\d{2})$/u;\n\n/**\n * Refines a string as an ISO 8601 date.\n */\nexport const ISO8601DateStruct = refine(string(), 'ISO 8601 date', (value) => {\n const parsedDate = DateTime.fromISO(value);\n\n if (!parsedDate.isValid) {\n return 'Not a valid ISO 8601 date';\n }\n\n if (!offsetRegex.test(value)) {\n // Luxon doesn't have a reliable way to check if timezone info was not provided\n return 'ISO 8601 date must have timezone information';\n }\n\n return true;\n});\n"]}
1
+ {"version":3,"file":"time.cjs","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":";;;AAAA,uDAAuD;AACvD,iCAA2C;AAE3C;;GAEG;AACU,QAAA,qBAAqB,GAAG,IAAA,oBAAM,EACzC,IAAA,oBAAM,GAAE,EACR,mBAAmB,EACnB,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,cAAc,GAAG,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;GAEG;AACU,QAAA,iBAAiB,GAAG,IAAA,oBAAM,EAAC,IAAA,oBAAM,GAAE,EAAE,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IAC3E,MAAM,UAAU,GAAG,gBAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,+EAA+E;QAC/E,OAAO,8CAA8C,CAAC;IACxD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,KAAa;IACnD,MAAM,IAAI,GAAG,gBAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,kDAAkD;IAClD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;QAClC,oBAAoB,EAAE,IAAI;KAC3B,CAAW,CAAC;AACf,CAAC;AAPD,0DAOC","sourcesContent":["import { refine, string } from '@metamask/superstruct';\nimport { DateTime, Duration } from 'luxon';\n\n/**\n * Refines a string as an ISO 8601 duration.\n */\nexport const ISO8601DurationStruct = refine(\n string(),\n 'ISO 8601 duration',\n (value) => {\n const parsedDuration = Duration.fromISO(value);\n if (!parsedDuration.isValid) {\n return 'Not a valid ISO 8601 duration';\n }\n\n return true;\n },\n);\n\n/**\n * Regex to match the offset part of an ISO 8601 date.\n */\nconst offsetRegex = /Z|([+-]\\d{2}:?\\d{2})$/u;\n\n/**\n * Refines a string as an ISO 8601 date.\n */\nexport const ISO8601DateStruct = refine(string(), 'ISO 8601 date', (value) => {\n const parsedDate = DateTime.fromISO(value);\n\n if (!parsedDate.isValid) {\n return 'Not a valid ISO 8601 date';\n }\n\n if (!offsetRegex.test(value)) {\n // Luxon doesn't have a reliable way to check if timezone info was not provided\n return 'ISO 8601 date must have timezone information';\n }\n\n return true;\n});\n\n/**\n * Remove millisecond precision from an ISO 8601 string.\n *\n * @param value - A valid ISO 8601 date.\n * @returns A valid ISO 8601 date with millisecond precision removed.\n */\nexport function toCensoredISO8601String(value: string) {\n const date = DateTime.fromISO(value, { setZone: true });\n\n // Make sure any millisecond precision is removed.\n return date.startOf('second').toISO({\n suppressMilliseconds: true,\n }) as string;\n}\n"]}
package/dist/time.d.cts CHANGED
@@ -6,4 +6,11 @@ export declare const ISO8601DurationStruct: import("@metamask/superstruct").Stru
6
6
  * Refines a string as an ISO 8601 date.
7
7
  */
8
8
  export declare const ISO8601DateStruct: import("@metamask/superstruct").Struct<string, null>;
9
+ /**
10
+ * Remove millisecond precision from an ISO 8601 string.
11
+ *
12
+ * @param value - A valid ISO 8601 date.
13
+ * @returns A valid ISO 8601 date with millisecond precision removed.
14
+ */
15
+ export declare function toCensoredISO8601String(value: string): string;
9
16
  //# sourceMappingURL=time.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.cts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,qBAAqB,sDAUjC,CAAC;AAOF;;GAEG;AACH,eAAO,MAAM,iBAAiB,sDAa5B,CAAC"}
1
+ {"version":3,"file":"time.d.cts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,qBAAqB,sDAWjC,CAAC;AAOF;;GAEG;AACH,eAAO,MAAM,iBAAiB,sDAa5B,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,UAOpD"}
package/dist/time.d.mts CHANGED
@@ -6,4 +6,11 @@ export declare const ISO8601DurationStruct: import("@metamask/superstruct").Stru
6
6
  * Refines a string as an ISO 8601 date.
7
7
  */
8
8
  export declare const ISO8601DateStruct: import("@metamask/superstruct").Struct<string, null>;
9
+ /**
10
+ * Remove millisecond precision from an ISO 8601 string.
11
+ *
12
+ * @param value - A valid ISO 8601 date.
13
+ * @returns A valid ISO 8601 date with millisecond precision removed.
14
+ */
15
+ export declare function toCensoredISO8601String(value: string): string;
9
16
  //# sourceMappingURL=time.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time.d.mts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,qBAAqB,sDAUjC,CAAC;AAOF;;GAEG;AACH,eAAO,MAAM,iBAAiB,sDAa5B,CAAC"}
1
+ {"version":3,"file":"time.d.mts","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,qBAAqB,sDAWjC,CAAC;AAOF;;GAEG;AACH,eAAO,MAAM,iBAAiB,sDAa5B,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,UAOpD"}
package/dist/time.mjs CHANGED
@@ -28,4 +28,17 @@ export const ISO8601DateStruct = refine(string(), 'ISO 8601 date', (value) => {
28
28
  }
29
29
  return true;
30
30
  });
31
+ /**
32
+ * Remove millisecond precision from an ISO 8601 string.
33
+ *
34
+ * @param value - A valid ISO 8601 date.
35
+ * @returns A valid ISO 8601 date with millisecond precision removed.
36
+ */
37
+ export function toCensoredISO8601String(value) {
38
+ const date = DateTime.fromISO(value, { setZone: true });
39
+ // Make sure any millisecond precision is removed.
40
+ return date.startOf('second').toISO({
41
+ suppressMilliseconds: true,
42
+ });
43
+ }
31
44
  //# sourceMappingURL=time.mjs.map
package/dist/time.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"time.mjs","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,8BAA8B;AACvD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CACzC,MAAM,EAAE,EACR,mBAAmB,EACnB,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,+BAA+B,CAAC;IACzC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IAC3E,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,+EAA+E;QAC/E,OAAO,8CAA8C,CAAC;IACxD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC","sourcesContent":["import { refine, string } from '@metamask/superstruct';\nimport { DateTime, Duration } from 'luxon';\n\n/**\n * Refines a string as an ISO 8601 duration.\n */\nexport const ISO8601DurationStruct = refine(\n string(),\n 'ISO 8601 duration',\n (value) => {\n const parsedDuration = Duration.fromISO(value);\n if (!parsedDuration.isValid) {\n return 'Not a valid ISO 8601 duration';\n }\n return true;\n },\n);\n\n/**\n * Regex to match the offset part of an ISO 8601 date.\n */\nconst offsetRegex = /Z|([+-]\\d{2}:?\\d{2})$/u;\n\n/**\n * Refines a string as an ISO 8601 date.\n */\nexport const ISO8601DateStruct = refine(string(), 'ISO 8601 date', (value) => {\n const parsedDate = DateTime.fromISO(value);\n\n if (!parsedDate.isValid) {\n return 'Not a valid ISO 8601 date';\n }\n\n if (!offsetRegex.test(value)) {\n // Luxon doesn't have a reliable way to check if timezone info was not provided\n return 'ISO 8601 date must have timezone information';\n }\n\n return true;\n});\n"]}
1
+ {"version":3,"file":"time.mjs","sourceRoot":"","sources":["../src/time.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,8BAA8B;AACvD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CACzC,MAAM,EAAE,EACR,mBAAmB,EACnB,CAAC,KAAK,EAAE,EAAE;IACR,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAO,+BAA+B,CAAC;IACzC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CACF,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IAC3E,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,2BAA2B,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,+EAA+E;QAC/E,OAAO,8CAA8C,CAAC;IACxD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAExD,kDAAkD;IAClD,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;QAClC,oBAAoB,EAAE,IAAI;KAC3B,CAAW,CAAC;AACf,CAAC","sourcesContent":["import { refine, string } from '@metamask/superstruct';\nimport { DateTime, Duration } from 'luxon';\n\n/**\n * Refines a string as an ISO 8601 duration.\n */\nexport const ISO8601DurationStruct = refine(\n string(),\n 'ISO 8601 duration',\n (value) => {\n const parsedDuration = Duration.fromISO(value);\n if (!parsedDuration.isValid) {\n return 'Not a valid ISO 8601 duration';\n }\n\n return true;\n },\n);\n\n/**\n * Regex to match the offset part of an ISO 8601 date.\n */\nconst offsetRegex = /Z|([+-]\\d{2}:?\\d{2})$/u;\n\n/**\n * Refines a string as an ISO 8601 date.\n */\nexport const ISO8601DateStruct = refine(string(), 'ISO 8601 date', (value) => {\n const parsedDate = DateTime.fromISO(value);\n\n if (!parsedDate.isValid) {\n return 'Not a valid ISO 8601 date';\n }\n\n if (!offsetRegex.test(value)) {\n // Luxon doesn't have a reliable way to check if timezone info was not provided\n return 'ISO 8601 date must have timezone information';\n }\n\n return true;\n});\n\n/**\n * Remove millisecond precision from an ISO 8601 string.\n *\n * @param value - A valid ISO 8601 date.\n * @returns A valid ISO 8601 date with millisecond precision removed.\n */\nexport function toCensoredISO8601String(value: string) {\n const date = DateTime.fromISO(value, { setZone: true });\n\n // Make sure any millisecond precision is removed.\n return date.startOf('second').toISO({\n suppressMilliseconds: true,\n }) as string;\n}\n"]}
@@ -35,6 +35,10 @@ class VirtualFile {
35
35
  this.data = options?.data ?? {};
36
36
  this.path = options?.path ?? '/';
37
37
  }
38
+ value;
39
+ result;
40
+ data;
41
+ path;
38
42
  get size() {
39
43
  return typeof this.value === 'string'
40
44
  ? this.value.length
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualFile.cjs","sourceRoot":"","sources":["../../src/virtual-file/VirtualFile.ts"],"names":[],"mappings":";;;AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;AACtD,2CAAqD;AACrD,sCAAqC;AAErC,kDAA0C;AA+B1C,MAAa,WAAW;IACtB,YAAY,KAA0B;QACpC,IAAI,OAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAC7D,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAK,SAAiB,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;IACnC,CAAC;IAUD,IAAI,IAAI;QACN,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,QAAiB;QACxB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAA,cAAM,EAAC,QAAQ,KAAK,SAAS,EAAE,yBAAyB,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YAClE,OAAO,IAAA,kBAAU,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrE,oEAAoE;YACpE,qCAAqC;YACrC,OAAO,aAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,WAAW,EAAU,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,mFAAmF;YACnF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,IAAA,sBAAS,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,GAAG,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAlED,kCAkEC","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-object-type\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 get size() {\n return typeof this.value === 'string'\n ? this.value.length\n : this.value.byteLength;\n }\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"]}
1
+ {"version":3,"file":"VirtualFile.cjs","sourceRoot":"","sources":["../../src/virtual-file/VirtualFile.ts"],"names":[],"mappings":";;;AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;AACtD,2CAAqD;AACrD,sCAAqC;AAErC,kDAA0C;AA+B1C,MAAa,WAAW;IACtB,YAAY,KAA0B;QACpC,IAAI,OAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAC7D,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAK,SAAiB,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;IACnC,CAAC;IAED,KAAK,CAAQ;IAEb,MAAM,CAAS;IAEf,IAAI,CAAO;IAEX,IAAI,CAAS;IAEb,IAAI,IAAI;QACN,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,QAAiB;QACxB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAA,cAAM,EAAC,QAAQ,KAAK,SAAS,EAAE,yBAAyB,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YAClE,OAAO,IAAA,kBAAU,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrE,oEAAoE;YACpE,qCAAqC;YACrC,OAAO,aAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,WAAW,EAAU,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,mFAAmF;YACnF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,IAAA,sBAAS,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,GAAG,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAlED,kCAkEC","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-object-type\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 get size() {\n return typeof this.value === 'string'\n ? this.value.length\n : this.value.byteLength;\n }\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"]}
@@ -32,6 +32,10 @@ export class VirtualFile {
32
32
  this.data = options?.data ?? {};
33
33
  this.path = options?.path ?? '/';
34
34
  }
35
+ value;
36
+ result;
37
+ data;
38
+ path;
35
39
  get size() {
36
40
  return typeof this.value === 'string'
37
41
  ? this.value.length
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualFile.mjs","sourceRoot":"","sources":["../../src/virtual-file/VirtualFile.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;AACtD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;AACrD,OAAO,EAAE,MAAM,EAAE,oBAAoB;AAErC,OAAO,EAAE,SAAS,EAAE,0BAAsB;AA+B1C,MAAM,OAAO,WAAW;IACtB,YAAY,KAA0B;QACpC,IAAI,OAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAC7D,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAK,SAAiB,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;IACnC,CAAC;IAUD,IAAI,IAAI;QACN,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,QAAiB;QACxB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,yBAAyB,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YAClE,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrE,oEAAoE;YACpE,qCAAqC;YACrC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,WAAW,EAAU,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,mFAAmF;YACnF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF","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-object-type\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 get size() {\n return typeof this.value === 'string'\n ? this.value.length\n : this.value.byteLength;\n }\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"]}
1
+ {"version":3,"file":"VirtualFile.mjs","sourceRoot":"","sources":["../../src/virtual-file/VirtualFile.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,iEAAiE;AACjE,2FAA2F;AAC3F,wFAAwF;AACxF,EAAE;AACF,oHAAoH;AACpH,qGAAqG;AACrG,sDAAsD;AACtD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;AACrD,OAAO,EAAE,MAAM,EAAE,oBAAoB;AAErC,OAAO,EAAE,SAAS,EAAE,0BAAsB;AA+B1C,MAAM,OAAO,WAAW;IACtB,YAAY,KAA0B;QACpC,IAAI,OAA4B,CAAC;QACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAC7D,OAAO,GAAG,EAAE,KAAK,EAAE,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QAClC,wDAAwD;QACxD,gEAAgE;QAChE,4DAA4D;QAC5D,EAAE;QACF,wEAAwE;QACxE,4EAA4E;QAC5E,8EAA8E;QAC9E,EAAE;QACF,iDAAiD;QACjD,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAK,SAAiB,CAAC;QACpD,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;IACnC,CAAC;IAED,KAAK,CAAQ;IAEb,MAAM,CAAS;IAEf,IAAI,CAAO;IAEX,IAAI,CAAS;IAEb,IAAI,IAAI;QACN,OAAO,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YACnB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;IAC5B,CAAC;IAED,QAAQ,CAAC,QAAiB;QACxB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,yBAAyB,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC,KAAK,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;YAClE,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,YAAY,UAAU,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACrE,oEAAoE;YACpE,qCAAqC;YACrC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,WAAW,EAAU,CAAC;QACxC,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,mFAAmF;YACnF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;CACF","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-object-type\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 get size() {\n return typeof this.value === 'string'\n ? this.value.length\n : this.value.byteLength;\n }\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-utils",
3
- "version": "9.3.0",
3
+ "version": "10.0.0",
4
4
  "description": "A collection of utilities for MetaMask Snaps",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -84,9 +84,9 @@
84
84
  "@metamask/key-tree": "^10.1.1",
85
85
  "@metamask/permission-controller": "^11.0.6",
86
86
  "@metamask/rpc-errors": "^7.0.2",
87
- "@metamask/slip44": "^4.1.0",
87
+ "@metamask/slip44": "^4.2.0",
88
88
  "@metamask/snaps-registry": "^3.2.3",
89
- "@metamask/snaps-sdk": "^6.24.0",
89
+ "@metamask/snaps-sdk": "^8.0.0",
90
90
  "@metamask/superstruct": "^3.2.1",
91
91
  "@metamask/utils": "^11.4.0",
92
92
  "@noble/hashes": "^1.7.1",
@@ -100,15 +100,15 @@
100
100
  "marked": "^12.0.1",
101
101
  "rfdc": "^1.3.0",
102
102
  "semver": "^7.5.4",
103
- "ses": "^1.12.0",
103
+ "ses": "^1.13.0",
104
104
  "validate-npm-package-name": "^5.0.0"
105
105
  },
106
106
  "devDependencies": {
107
107
  "@lavamoat/allow-scripts": "^3.3.3",
108
108
  "@metamask/auto-changelog": "^5.0.2",
109
109
  "@metamask/post-message-stream": "^10.0.0",
110
- "@swc/core": "1.3.78",
111
- "@swc/jest": "^0.2.26",
110
+ "@swc/core": "1.11.31",
111
+ "@swc/jest": "^0.2.38",
112
112
  "@testing-library/dom": "^10.4.0",
113
113
  "@ts-bridge/cli": "^0.6.1",
114
114
  "@types/jest": "^27.5.1",
@@ -125,6 +125,7 @@
125
125
  "istanbul-lib-report": "^3.0.0",
126
126
  "istanbul-reports": "^3.1.5",
127
127
  "jest": "^29.0.2",
128
+ "jest-fetch-mock": "^3.0.3",
128
129
  "jest-silent-reporter": "^0.6.0",
129
130
  "memfs": "^3.4.13",
130
131
  "prettier": "^3.3.3",
@@ -137,7 +138,7 @@
137
138
  "vitest": "^3.1.1"
138
139
  },
139
140
  "engines": {
140
- "node": "^18.16 || >=20"
141
+ "node": "^20 || >=22"
141
142
  },
142
143
  "publishConfig": {
143
144
  "access": "public",