@metamask/snaps-execution-environments 11.0.1 → 11.1.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.
- package/CHANGELOG.md +22 -1
- package/dist/common/BaseSnapExecutor.cjs.map +1 -1
- package/dist/common/BaseSnapExecutor.d.cts +2 -2
- package/dist/common/BaseSnapExecutor.d.cts.map +1 -1
- package/dist/common/BaseSnapExecutor.d.mts +2 -2
- package/dist/common/BaseSnapExecutor.d.mts.map +1 -1
- package/dist/common/BaseSnapExecutor.mjs.map +1 -1
- package/dist/common/endowments/commonEndowmentFactory.cjs.map +1 -1
- package/dist/common/endowments/commonEndowmentFactory.d.cts +44 -5
- package/dist/common/endowments/commonEndowmentFactory.d.cts.map +1 -1
- package/dist/common/endowments/commonEndowmentFactory.d.mts +44 -5
- package/dist/common/endowments/commonEndowmentFactory.d.mts.map +1 -1
- package/dist/common/endowments/commonEndowmentFactory.mjs.map +1 -1
- package/dist/common/endowments/console.cjs +13 -12
- package/dist/common/endowments/console.cjs.map +1 -1
- package/dist/common/endowments/console.d.cts +8 -7
- package/dist/common/endowments/console.d.cts.map +1 -1
- package/dist/common/endowments/console.d.mts +8 -7
- package/dist/common/endowments/console.d.mts.map +1 -1
- package/dist/common/endowments/console.mjs +13 -12
- package/dist/common/endowments/console.mjs.map +1 -1
- package/dist/common/endowments/index.cjs +1 -1
- package/dist/common/endowments/index.cjs.map +1 -1
- package/dist/common/endowments/index.d.cts +1 -1
- package/dist/common/endowments/index.d.cts.map +1 -1
- package/dist/common/endowments/index.d.mts +1 -1
- package/dist/common/endowments/index.d.mts.map +1 -1
- package/dist/common/endowments/index.mjs +1 -1
- package/dist/common/endowments/index.mjs.map +1 -1
- package/dist/common/endowments/network.cjs +5 -4
- package/dist/common/endowments/network.cjs.map +1 -1
- package/dist/common/endowments/network.d.cts.map +1 -1
- package/dist/common/endowments/network.d.mts.map +1 -1
- package/dist/common/endowments/network.mjs +5 -4
- package/dist/common/endowments/network.mjs.map +1 -1
- package/dist/common/validation.d.cts +17 -17
- package/dist/common/validation.d.mts +17 -17
- package/dist/endowments.cjs +61 -0
- package/dist/endowments.cjs.map +1 -0
- package/dist/endowments.d.cts +59 -0
- package/dist/endowments.d.cts.map +1 -0
- package/dist/endowments.d.mts +59 -0
- package/dist/endowments.d.mts.map +1 -0
- package/dist/endowments.mjs +47 -0
- package/dist/endowments.mjs.map +1 -0
- package/dist/webpack/iframe/bundle.js +1 -1
- package/dist/webpack/node-process/bundle.js +417 -270
- package/dist/webpack/node-process/bundle.js.LICENSE.txt +416 -269
- package/dist/webpack/node-thread/bundle.js +417 -270
- package/dist/webpack/node-thread/bundle.js.LICENSE.txt +416 -269
- package/dist/webpack/webview/index.html +1 -1
- package/package.json +18 -8
|
@@ -12,8 +12,9 @@ exports.consoleAttenuatedMethods = new Set([
|
|
|
12
12
|
'warn',
|
|
13
13
|
]);
|
|
14
14
|
/**
|
|
15
|
-
* A set of all the `console`
|
|
16
|
-
*
|
|
15
|
+
* A set of all the `console` method names that will be included in the
|
|
16
|
+
* attenuated console object. Covers values available in both browser and
|
|
17
|
+
* Node.js.
|
|
17
18
|
*/
|
|
18
19
|
exports.consoleMethods = new Set([
|
|
19
20
|
'debug',
|
|
@@ -45,13 +46,13 @@ const consoleFunctions = ['log', 'error', 'debug', 'info', 'warn'];
|
|
|
45
46
|
* Gets the appropriate (prepended) message to pass to one of the attenuated
|
|
46
47
|
* method calls.
|
|
47
48
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param message - The
|
|
49
|
+
* @param sourceLabel - Label identifying the source of the console call.
|
|
50
|
+
* @param message - The first argument passed to the console method.
|
|
50
51
|
* @param args - The array of additional arguments.
|
|
51
52
|
* @returns An array of arguments to be passed into an attenuated console method call.
|
|
52
53
|
*/
|
|
53
|
-
function getMessage(
|
|
54
|
-
const prefix = `[
|
|
54
|
+
function getMessage(sourceLabel, message, ...args) {
|
|
55
|
+
const prefix = `[${sourceLabel}]`;
|
|
55
56
|
// If the first argument is a string, prepend the prefix to the message, and keep the
|
|
56
57
|
// rest of the arguments as-is.
|
|
57
58
|
if (typeof message === 'string') {
|
|
@@ -62,15 +63,15 @@ function getMessage(snapId, message, ...args) {
|
|
|
62
63
|
return [prefix, message, ...args];
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
|
-
* Create a
|
|
66
|
+
* Create a {@link console} object, with the same properties as the global
|
|
66
67
|
* {@link console} object, but with some methods replaced.
|
|
67
68
|
*
|
|
68
69
|
* @param options - Factory options used in construction of the endowment.
|
|
69
|
-
* @param options.
|
|
70
|
+
* @param options.sourceLabel - Label identifying the source of the console call.
|
|
70
71
|
* @returns The {@link console} object with the replaced methods.
|
|
71
72
|
*/
|
|
72
|
-
function createConsole({
|
|
73
|
-
(0, utils_1.assert)(
|
|
73
|
+
function createConsole({ sourceLabel } = {}) {
|
|
74
|
+
(0, utils_1.assert)(sourceLabel !== undefined, 'The "sourceLabel" option is required by the console endowment factory.');
|
|
74
75
|
const keys = Object.getOwnPropertyNames(globalObject_1.rootRealmGlobal.console);
|
|
75
76
|
const attenuatedConsole = keys.reduce((target, key) => {
|
|
76
77
|
if (exports.consoleMethods.has(key) && !exports.consoleAttenuatedMethods.has(key)) {
|
|
@@ -82,13 +83,13 @@ function createConsole({ snapId } = {}) {
|
|
|
82
83
|
console: {
|
|
83
84
|
...attenuatedConsole,
|
|
84
85
|
assert: (value, message, ...optionalParams) => {
|
|
85
|
-
globalObject_1.rootRealmGlobal.console.assert(value, ...getMessage(
|
|
86
|
+
globalObject_1.rootRealmGlobal.console.assert(value, ...getMessage(sourceLabel, message, ...optionalParams));
|
|
86
87
|
},
|
|
87
88
|
...consoleFunctions.reduce((target, key) => {
|
|
88
89
|
return {
|
|
89
90
|
...target,
|
|
90
91
|
[key]: (message, ...optionalParams) => {
|
|
91
|
-
globalObject_1.rootRealmGlobal.console[key](...getMessage(
|
|
92
|
+
globalObject_1.rootRealmGlobal.console[key](...getMessage(sourceLabel, message, ...optionalParams));
|
|
92
93
|
},
|
|
93
94
|
};
|
|
94
95
|
}, {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.cjs","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AAGzC,sDAAkD;AAErC,QAAA,wBAAwB,GAAG,IAAI,GAAG,CAAC;IAC9C,KAAK;IACL,QAAQ;IACR,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"console.cjs","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AAGzC,sDAAkD;AAErC,QAAA,wBAAwB,GAAG,IAAI,GAAG,CAAC;IAC9C,KAAK;IACL,QAAQ;IACR,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH;;;;GAIG;AACU,QAAA,cAAc,GAAG,IAAI,GAAG,CAAC;IACpC,OAAO;IACP,OAAO;IACP,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,QAAQ;IACR,OAAO;IACP,OAAO;IACP,OAAO;IACP,gBAAgB;IAChB,UAAU;IACV,OAAO;IACP,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,YAAY;IACZ,MAAM;IACN,SAAS;IACT,SAAS;IACT,WAAW;IACX,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAM5E;;;;;;;;GAQG;AACH,SAAS,UAAU,CAAC,WAAmB,EAAE,OAAgB,EAAE,GAAG,IAAe;IAC3E,MAAM,MAAM,GAAG,IAAI,WAAW,GAAG,CAAC;IAElC,qFAAqF;IACrF,+BAA+B;IAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,sFAAsF;IACtF,4BAA4B;IAC5B,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,EAAE,WAAW,KAA8B,EAAE;IAClE,IAAA,cAAM,EACJ,WAAW,KAAK,SAAS,EACzB,wEAAwE,CACzE,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,CAAC,mBAAmB,CACrC,8BAAe,CAAC,OAAO,CACI,CAAC;IAE9B,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACpD,IAAI,sBAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAwB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,8BAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,MAAM,CAAC;QACZ,OAAO,EAAE;YACP,GAAG,iBAAiB;YACpB,MAAM,EAAE,CACN,KAAU,EACV,OAA4B,EAC5B,GAAG,cAAqB,EACxB,EAAE;gBACF,8BAAe,CAAC,OAAO,CAAC,MAAM,CAC5B,KAAK,EACL,GAAG,UAAU,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,CACvD,CAAC;YACJ,CAAC;YACD,GAAG,gBAAgB,CAAC,MAAM,CAAmB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;gBAC3D,OAAO;oBACL,GAAG,MAAM;oBACT,CAAC,GAAG,CAAC,EAAE,CAAC,OAAiB,EAAE,GAAG,cAAqB,EAAE,EAAE;wBACrD,8BAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAC1B,GAAG,UAAU,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,CACvD,CAAC;oBACJ,CAAC;iBACF,CAAC;YACJ,CAAC,EAAE,EAAsB,CAAC;SAC3B;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,eAAe,GAAG;IACtB,KAAK,EAAE,CAAC,SAAS,CAAU;IAC3B,OAAO,EAAE,aAAa;CACvB,CAAC;AAEF,kBAAe,eAAe,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport { rootRealmGlobal } from '../globalObject';\n\nexport const consoleAttenuatedMethods = new Set([\n 'log',\n 'assert',\n 'error',\n 'debug',\n 'info',\n 'warn',\n]);\n\n/**\n * A set of all the `console` method names that will be included in the\n * attenuated console object. Covers values available in both browser and\n * Node.js.\n */\nexport const consoleMethods = new Set([\n 'debug',\n 'error',\n 'info',\n 'log',\n 'warn',\n 'dir',\n 'dirxml',\n 'table',\n 'trace',\n 'group',\n 'groupCollapsed',\n 'groupEnd',\n 'clear',\n 'count',\n 'countReset',\n 'assert',\n 'profile',\n 'profileEnd',\n 'time',\n 'timeLog',\n 'timeEnd',\n 'timeStamp',\n 'context',\n]);\n\nconst consoleFunctions = ['log', 'error', 'debug', 'info', 'warn'] as const;\n\ntype ConsoleFunctions = {\n [Key in (typeof consoleFunctions)[number]]: (typeof rootRealmGlobal.console)[Key];\n};\n\n/**\n * Gets the appropriate (prepended) message to pass to one of the attenuated\n * method calls.\n *\n * @param sourceLabel - Label identifying the source of the console call.\n * @param message - The first argument passed to the console method.\n * @param args - The array of additional arguments.\n * @returns An array of arguments to be passed into an attenuated console method call.\n */\nfunction getMessage(sourceLabel: string, message: unknown, ...args: unknown[]) {\n const prefix = `[${sourceLabel}]`;\n\n // If the first argument is a string, prepend the prefix to the message, and keep the\n // rest of the arguments as-is.\n if (typeof message === 'string') {\n return [`${prefix} ${message}`, ...args];\n }\n\n // Otherwise, the `message` is an object, array, etc., so add the prefix as a separate\n // message to the arguments.\n return [prefix, message, ...args];\n}\n\n/**\n * Create a {@link console} object, with the same properties as the global\n * {@link console} object, but with some methods replaced.\n *\n * @param options - Factory options used in construction of the endowment.\n * @param options.sourceLabel - Label identifying the source of the console call.\n * @returns The {@link console} object with the replaced methods.\n */\nfunction createConsole({ sourceLabel }: EndowmentFactoryOptions = {}) {\n assert(\n sourceLabel !== undefined,\n 'The \"sourceLabel\" option is required by the console endowment factory.',\n );\n const keys = Object.getOwnPropertyNames(\n rootRealmGlobal.console,\n ) as (keyof typeof console)[];\n\n const attenuatedConsole = keys.reduce((target, key) => {\n if (consoleMethods.has(key) && !consoleAttenuatedMethods.has(key)) {\n return { ...target, [key]: rootRealmGlobal.console[key] };\n }\n\n return target;\n }, {});\n\n return harden({\n console: {\n ...attenuatedConsole,\n assert: (\n value: any,\n message?: string | undefined,\n ...optionalParams: any[]\n ) => {\n rootRealmGlobal.console.assert(\n value,\n ...getMessage(sourceLabel, message, ...optionalParams),\n );\n },\n ...consoleFunctions.reduce<ConsoleFunctions>((target, key) => {\n return {\n ...target,\n [key]: (message?: unknown, ...optionalParams: any[]) => {\n rootRealmGlobal.console[key](\n ...getMessage(sourceLabel, message, ...optionalParams),\n );\n },\n };\n }, {} as ConsoleFunctions),\n },\n });\n}\n\nconst endowmentModule = {\n names: ['console'] as const,\n factory: createConsole,\n};\n\nexport default endowmentModule;\n"]}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import type { EndowmentFactoryOptions } from "./commonEndowmentFactory.cjs";
|
|
2
2
|
export declare const consoleAttenuatedMethods: Set<string>;
|
|
3
3
|
/**
|
|
4
|
-
* A set of all the `console`
|
|
5
|
-
*
|
|
4
|
+
* A set of all the `console` method names that will be included in the
|
|
5
|
+
* attenuated console object. Covers values available in both browser and
|
|
6
|
+
* Node.js.
|
|
6
7
|
*/
|
|
7
8
|
export declare const consoleMethods: Set<string>;
|
|
8
9
|
/**
|
|
9
|
-
* Create a
|
|
10
|
+
* Create a {@link console} object, with the same properties as the global
|
|
10
11
|
* {@link console} object, but with some methods replaced.
|
|
11
12
|
*
|
|
12
13
|
* @param options - Factory options used in construction of the endowment.
|
|
13
|
-
* @param options.
|
|
14
|
+
* @param options.sourceLabel - Label identifying the source of the console call.
|
|
14
15
|
* @returns The {@link console} object with the replaced methods.
|
|
15
16
|
*/
|
|
16
|
-
declare function createConsole({
|
|
17
|
+
declare function createConsole({ sourceLabel }?: EndowmentFactoryOptions): {
|
|
17
18
|
console: {
|
|
18
|
-
|
|
19
|
+
log: {
|
|
19
20
|
(...data: any[]): void;
|
|
20
21
|
(message?: any, ...optionalParams: any[]): void;
|
|
21
22
|
};
|
|
22
|
-
|
|
23
|
+
error: {
|
|
23
24
|
(...data: any[]): void;
|
|
24
25
|
(message?: any, ...optionalParams: any[]): void;
|
|
25
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE,eAAO,MAAM,wBAAwB,aAOnC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"console.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE,eAAO,MAAM,wBAAwB,aAOnC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc,aAwBzB,CAAC;AA+BH;;;;;;;GAOG;AACH,iBAAS,aAAa,CAAC,EAAE,WAAW,EAAE,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;wBAqBrD,GAAG,YACA,MAAM,GAAG,SAAS,qBACT,GAAG,EAAE;;EAmB/B;AAED,QAAA,MAAM,eAAe;;;CAGpB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import type { EndowmentFactoryOptions } from "./commonEndowmentFactory.mjs";
|
|
2
2
|
export declare const consoleAttenuatedMethods: Set<string>;
|
|
3
3
|
/**
|
|
4
|
-
* A set of all the `console`
|
|
5
|
-
*
|
|
4
|
+
* A set of all the `console` method names that will be included in the
|
|
5
|
+
* attenuated console object. Covers values available in both browser and
|
|
6
|
+
* Node.js.
|
|
6
7
|
*/
|
|
7
8
|
export declare const consoleMethods: Set<string>;
|
|
8
9
|
/**
|
|
9
|
-
* Create a
|
|
10
|
+
* Create a {@link console} object, with the same properties as the global
|
|
10
11
|
* {@link console} object, but with some methods replaced.
|
|
11
12
|
*
|
|
12
13
|
* @param options - Factory options used in construction of the endowment.
|
|
13
|
-
* @param options.
|
|
14
|
+
* @param options.sourceLabel - Label identifying the source of the console call.
|
|
14
15
|
* @returns The {@link console} object with the replaced methods.
|
|
15
16
|
*/
|
|
16
|
-
declare function createConsole({
|
|
17
|
+
declare function createConsole({ sourceLabel }?: EndowmentFactoryOptions): {
|
|
17
18
|
console: {
|
|
18
|
-
|
|
19
|
+
log: {
|
|
19
20
|
(...data: any[]): void;
|
|
20
21
|
(message?: any, ...optionalParams: any[]): void;
|
|
21
22
|
};
|
|
22
|
-
|
|
23
|
+
error: {
|
|
23
24
|
(...data: any[]): void;
|
|
24
25
|
(message?: any, ...optionalParams: any[]): void;
|
|
25
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE,eAAO,MAAM,wBAAwB,aAOnC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"console.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE,eAAO,MAAM,wBAAwB,aAOnC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc,aAwBzB,CAAC;AA+BH;;;;;;;GAOG;AACH,iBAAS,aAAa,CAAC,EAAE,WAAW,EAAE,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;wBAqBrD,GAAG,YACA,MAAM,GAAG,SAAS,qBACT,GAAG,EAAE;;EAmB/B;AAED,QAAA,MAAM,eAAe;;;CAGpB,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -9,8 +9,9 @@ export const consoleAttenuatedMethods = new Set([
|
|
|
9
9
|
'warn',
|
|
10
10
|
]);
|
|
11
11
|
/**
|
|
12
|
-
* A set of all the `console`
|
|
13
|
-
*
|
|
12
|
+
* A set of all the `console` method names that will be included in the
|
|
13
|
+
* attenuated console object. Covers values available in both browser and
|
|
14
|
+
* Node.js.
|
|
14
15
|
*/
|
|
15
16
|
export const consoleMethods = new Set([
|
|
16
17
|
'debug',
|
|
@@ -42,13 +43,13 @@ const consoleFunctions = ['log', 'error', 'debug', 'info', 'warn'];
|
|
|
42
43
|
* Gets the appropriate (prepended) message to pass to one of the attenuated
|
|
43
44
|
* method calls.
|
|
44
45
|
*
|
|
45
|
-
* @param
|
|
46
|
-
* @param message - The
|
|
46
|
+
* @param sourceLabel - Label identifying the source of the console call.
|
|
47
|
+
* @param message - The first argument passed to the console method.
|
|
47
48
|
* @param args - The array of additional arguments.
|
|
48
49
|
* @returns An array of arguments to be passed into an attenuated console method call.
|
|
49
50
|
*/
|
|
50
|
-
function getMessage(
|
|
51
|
-
const prefix = `[
|
|
51
|
+
function getMessage(sourceLabel, message, ...args) {
|
|
52
|
+
const prefix = `[${sourceLabel}]`;
|
|
52
53
|
// If the first argument is a string, prepend the prefix to the message, and keep the
|
|
53
54
|
// rest of the arguments as-is.
|
|
54
55
|
if (typeof message === 'string') {
|
|
@@ -59,15 +60,15 @@ function getMessage(snapId, message, ...args) {
|
|
|
59
60
|
return [prefix, message, ...args];
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
|
-
* Create a
|
|
63
|
+
* Create a {@link console} object, with the same properties as the global
|
|
63
64
|
* {@link console} object, but with some methods replaced.
|
|
64
65
|
*
|
|
65
66
|
* @param options - Factory options used in construction of the endowment.
|
|
66
|
-
* @param options.
|
|
67
|
+
* @param options.sourceLabel - Label identifying the source of the console call.
|
|
67
68
|
* @returns The {@link console} object with the replaced methods.
|
|
68
69
|
*/
|
|
69
|
-
function createConsole({
|
|
70
|
-
assert(
|
|
70
|
+
function createConsole({ sourceLabel } = {}) {
|
|
71
|
+
assert(sourceLabel !== undefined, 'The "sourceLabel" option is required by the console endowment factory.');
|
|
71
72
|
const keys = Object.getOwnPropertyNames(rootRealmGlobal.console);
|
|
72
73
|
const attenuatedConsole = keys.reduce((target, key) => {
|
|
73
74
|
if (consoleMethods.has(key) && !consoleAttenuatedMethods.has(key)) {
|
|
@@ -79,13 +80,13 @@ function createConsole({ snapId } = {}) {
|
|
|
79
80
|
console: {
|
|
80
81
|
...attenuatedConsole,
|
|
81
82
|
assert: (value, message, ...optionalParams) => {
|
|
82
|
-
rootRealmGlobal.console.assert(value, ...getMessage(
|
|
83
|
+
rootRealmGlobal.console.assert(value, ...getMessage(sourceLabel, message, ...optionalParams));
|
|
83
84
|
},
|
|
84
85
|
...consoleFunctions.reduce((target, key) => {
|
|
85
86
|
return {
|
|
86
87
|
...target,
|
|
87
88
|
[key]: (message, ...optionalParams) => {
|
|
88
|
-
rootRealmGlobal.console[key](...getMessage(
|
|
89
|
+
rootRealmGlobal.console[key](...getMessage(sourceLabel, message, ...optionalParams));
|
|
89
90
|
},
|
|
90
91
|
};
|
|
91
92
|
}, {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"console.mjs","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAGzC,OAAO,EAAE,eAAe,EAAE,4BAAwB;AAElD,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC;IAC9C,KAAK;IACL,QAAQ;IACR,OAAO;IACP,OAAO;IACP,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH
|
|
1
|
+
{"version":3,"file":"console.mjs","sourceRoot":"","sources":["../../../src/common/endowments/console.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport { rootRealmGlobal } from '../globalObject';\n\nexport const consoleAttenuatedMethods = new Set([\n 'log',\n 'assert',\n 'error',\n 'debug',\n 'info',\n 'warn',\n]);\n\n/**\n * A set of all the `console` method names that will be included in the\n * attenuated console object. Covers values available in both browser and\n * Node.js.\n */\nexport const consoleMethods = new Set([\n 'debug',\n 'error',\n 'info',\n 'log',\n 'warn',\n 'dir',\n 'dirxml',\n 'table',\n 'trace',\n 'group',\n 'groupCollapsed',\n 'groupEnd',\n 'clear',\n 'count',\n 'countReset',\n 'assert',\n 'profile',\n 'profileEnd',\n 'time',\n 'timeLog',\n 'timeEnd',\n 'timeStamp',\n 'context',\n]);\n\nconst consoleFunctions = ['log', 'error', 'debug', 'info', 'warn'] as const;\n\ntype ConsoleFunctions = {\n [Key in (typeof consoleFunctions)[number]]: (typeof rootRealmGlobal.console)[Key];\n};\n\n/**\n * Gets the appropriate (prepended) message to pass to one of the attenuated\n * method calls.\n *\n * @param sourceLabel - Label identifying the source of the console call.\n * @param message - The first argument passed to the console method.\n * @param args - The array of additional arguments.\n * @returns An array of arguments to be passed into an attenuated console method call.\n */\nfunction getMessage(sourceLabel: string, message: unknown, ...args: unknown[]) {\n const prefix = `[${sourceLabel}]`;\n\n // If the first argument is a string, prepend the prefix to the message, and keep the\n // rest of the arguments as-is.\n if (typeof message === 'string') {\n return [`${prefix} ${message}`, ...args];\n }\n\n // Otherwise, the `message` is an object, array, etc., so add the prefix as a separate\n // message to the arguments.\n return [prefix, message, ...args];\n}\n\n/**\n * Create a {@link console} object, with the same properties as the global\n * {@link console} object, but with some methods replaced.\n *\n * @param options - Factory options used in construction of the endowment.\n * @param options.sourceLabel - Label identifying the source of the console call.\n * @returns The {@link console} object with the replaced methods.\n */\nfunction createConsole({ sourceLabel }: EndowmentFactoryOptions = {}) {\n assert(\n sourceLabel !== undefined,\n 'The \"sourceLabel\" option is required by the console endowment factory.',\n );\n const keys = Object.getOwnPropertyNames(\n rootRealmGlobal.console,\n ) as (keyof typeof console)[];\n\n const attenuatedConsole = keys.reduce((target, key) => {\n if (consoleMethods.has(key) && !consoleAttenuatedMethods.has(key)) {\n return { ...target, [key]: rootRealmGlobal.console[key] };\n }\n\n return target;\n }, {});\n\n return harden({\n console: {\n ...attenuatedConsole,\n assert: (\n value: any,\n message?: string | undefined,\n ...optionalParams: any[]\n ) => {\n rootRealmGlobal.console.assert(\n value,\n ...getMessage(sourceLabel, message, ...optionalParams),\n );\n },\n ...consoleFunctions.reduce<ConsoleFunctions>((target, key) => {\n return {\n ...target,\n [key]: (message?: unknown, ...optionalParams: any[]) => {\n rootRealmGlobal.console[key](\n ...getMessage(sourceLabel, message, ...optionalParams),\n );\n },\n };\n }, {} as ConsoleFunctions),\n },\n });\n}\n\nconst endowmentModule = {\n names: ['console'] as const,\n factory: createConsole,\n};\n\nexport default endowmentModule;\n"]}
|
|
@@ -55,7 +55,7 @@ function createEndowments({ snap, ethereum, snapId, endowments, notify, }) {
|
|
|
55
55
|
// This may not have an actual use case, but, safety first.
|
|
56
56
|
// We just confirmed that endowmentFactories has the specified key.
|
|
57
57
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
58
|
-
const { teardownFunction, ...endowment } = endowmentFactories.get(endowmentName)({ snapId
|
|
58
|
+
const { teardownFunction, ...endowment } = endowmentFactories.get(endowmentName)({ sourceLabel: `Snap: ${snapId}`, notify });
|
|
59
59
|
Object.assign(attenuatedEndowments, endowment);
|
|
60
60
|
if (teardownFunction) {
|
|
61
61
|
teardowns.push(teardownFunction);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":";;;;;;AAAA,qDAAiD;AAEjD,uDAAmD;AACnD,2CAA8C;
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { logWarning } from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport type {\n EndowmentFactoryOptions,\n EndowmentFactoryResult,\n NotifyFunction,\n} from './commonEndowmentFactory';\nimport buildCommonEndowments from './commonEndowmentFactory';\nimport { rootRealmGlobal } from '../globalObject';\n\n/**\n * Retrieve consolidated endowment factories for common endowments.\n */\nconst registeredEndowments = buildCommonEndowments();\n\n/**\n * A map of endowment names to their factory functions. Some endowments share\n * the same factory function, but we only call each factory once for each snap.\n * See {@link createEndowments} for details.\n */\nconst endowmentFactories = registeredEndowments.reduce((factories, builder) => {\n builder.names.forEach((name) => {\n factories.set(name, builder.factory);\n });\n return factories;\n}, new Map<string, (options?: EndowmentFactoryOptions) => EndowmentFactoryResult>());\n\n/**\n * Gets the endowments for a particular Snap. Some endowments, like `setTimeout`\n * and `clearTimeout`, must be attenuated so that they can only affect behavior\n * within the Snap's own realm. Therefore, we use factory functions to create\n * such attenuated / modified endowments. Otherwise, the value that's on the\n * root realm global will be used.\n *\n * @param options - An options bag.\n * @param options.snap - The Snaps global API object.\n * @param options.ethereum - The Snap's EIP-1193 provider object.\n * @param options.snapId - The id of the snap that will use the created endowments.\n * @param options.endowments - The list of endowments to provide to the snap.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing the Snap's endowments.\n */\nexport function createEndowments({\n snap,\n ethereum,\n snapId,\n endowments,\n notify,\n}: {\n snap: SnapsProvider;\n ethereum: SnapsEthereumProvider;\n snapId: string;\n endowments: string[];\n notify: NotifyFunction;\n}): { endowments: Record<string, unknown>; teardown: () => Promise<void> } {\n const attenuatedEndowments: Record<string, unknown> = {};\n\n // TODO: All endowments should be hardened to prevent covert communication\n // channels. Hardening the returned objects breaks tests elsewhere in the\n // monorepo, so further research is needed.\n const result = endowments.reduce<{\n allEndowments: Record<string, unknown>;\n teardowns: (() => Promise<void> | void)[];\n }>(\n ({ allEndowments, teardowns }, endowmentName) => {\n // First, check if the endowment has a factory, and default to that.\n if (endowmentFactories.has(endowmentName)) {\n if (!hasProperty(attenuatedEndowments, endowmentName)) {\n // Call the endowment factory for the current endowment. If the factory\n // creates multiple endowments, they will all be assigned to the\n // `attenuatedEndowments` object, but will only be passed on to the snap\n // if explicitly listed among its endowment.\n // This may not have an actual use case, but, safety first.\n\n // We just confirmed that endowmentFactories has the specified key.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { teardownFunction, ...endowment } = endowmentFactories.get(\n endowmentName,\n )!({ sourceLabel: `Snap: ${snapId}`, notify });\n Object.assign(attenuatedEndowments, endowment);\n if (teardownFunction) {\n teardowns.push(teardownFunction);\n }\n }\n allEndowments[endowmentName] = attenuatedEndowments[endowmentName];\n } else if (endowmentName === 'ethereum') {\n // Special case for adding the EIP-1193 provider.\n allEndowments[endowmentName] = ethereum;\n } else if (endowmentName in rootRealmGlobal) {\n logWarning(`Access to unhardened global ${endowmentName}.`);\n // If the endowment doesn't have a factory, just use whatever is on the\n // global object.\n const globalValue = (rootRealmGlobal as Record<string, unknown>)[\n endowmentName\n ];\n allEndowments[endowmentName] = globalValue;\n } else {\n // If we get to this point, we've been passed an endowment that doesn't\n // exist in our current environment.\n throw rpcErrors.internal(`Unknown endowment: \"${endowmentName}\".`);\n }\n return { allEndowments, teardowns };\n },\n {\n allEndowments: { snap },\n teardowns: [],\n },\n );\n\n const teardown = async () => {\n await Promise.all(\n result.teardowns.map(async (teardownFunction) => teardownFunction()),\n );\n };\n return { endowments: result.allEndowments, teardown };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SnapsEthereumProvider, SnapsProvider } from "@metamask/snaps-sdk";
|
|
2
|
-
import type { NotifyFunction } from "
|
|
2
|
+
import type { NotifyFunction } from "./commonEndowmentFactory.cjs";
|
|
3
3
|
/**
|
|
4
4
|
* Gets the endowments for a particular Snap. Some endowments, like `setTimeout`
|
|
5
5
|
* and `clearTimeout`, must be attenuated so that they can only affect behavior
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,4BAA4B;AAIhF,OAAO,KAAK,EAGV,cAAc,EACf,qCAAiC;AAqBlC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE;IACD,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA6DzE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SnapsEthereumProvider, SnapsProvider } from "@metamask/snaps-sdk";
|
|
2
|
-
import type { NotifyFunction } from "
|
|
2
|
+
import type { NotifyFunction } from "./commonEndowmentFactory.mjs";
|
|
3
3
|
/**
|
|
4
4
|
* Gets the endowments for a particular Snap. Some endowments, like `setTimeout`
|
|
5
5
|
* and `clearTimeout`, must be attenuated so that they can only affect behavior
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,4BAA4B;
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,4BAA4B;AAIhF,OAAO,KAAK,EAGV,cAAc,EACf,qCAAiC;AAqBlC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,UAAU,EACV,MAAM,GACP,EAAE;IACD,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,qBAAqB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA6DzE"}
|
|
@@ -49,7 +49,7 @@ export function createEndowments({ snap, ethereum, snapId, endowments, notify, }
|
|
|
49
49
|
// This may not have an actual use case, but, safety first.
|
|
50
50
|
// We just confirmed that endowmentFactories has the specified key.
|
|
51
51
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
52
|
-
const { teardownFunction, ...endowment } = endowmentFactories.get(endowmentName)({ snapId
|
|
52
|
+
const { teardownFunction, ...endowment } = endowmentFactories.get(endowmentName)({ sourceLabel: `Snap: ${snapId}`, notify });
|
|
53
53
|
Object.assign(attenuatedEndowments, endowment);
|
|
54
54
|
if (teardownFunction) {
|
|
55
55
|
teardowns.push(teardownFunction);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,6BAA6B;AAEjD,OAAO,EAAE,UAAU,EAAE,8BAA8B;AACnD,OAAO,EAAE,WAAW,EAAE,wBAAwB;
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../../src/common/endowments/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { rpcErrors } from '@metamask/rpc-errors';\nimport type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';\nimport { logWarning } from '@metamask/snaps-utils';\nimport { hasProperty } from '@metamask/utils';\n\nimport type {\n EndowmentFactoryOptions,\n EndowmentFactoryResult,\n NotifyFunction,\n} from './commonEndowmentFactory';\nimport buildCommonEndowments from './commonEndowmentFactory';\nimport { rootRealmGlobal } from '../globalObject';\n\n/**\n * Retrieve consolidated endowment factories for common endowments.\n */\nconst registeredEndowments = buildCommonEndowments();\n\n/**\n * A map of endowment names to their factory functions. Some endowments share\n * the same factory function, but we only call each factory once for each snap.\n * See {@link createEndowments} for details.\n */\nconst endowmentFactories = registeredEndowments.reduce((factories, builder) => {\n builder.names.forEach((name) => {\n factories.set(name, builder.factory);\n });\n return factories;\n}, new Map<string, (options?: EndowmentFactoryOptions) => EndowmentFactoryResult>());\n\n/**\n * Gets the endowments for a particular Snap. Some endowments, like `setTimeout`\n * and `clearTimeout`, must be attenuated so that they can only affect behavior\n * within the Snap's own realm. Therefore, we use factory functions to create\n * such attenuated / modified endowments. Otherwise, the value that's on the\n * root realm global will be used.\n *\n * @param options - An options bag.\n * @param options.snap - The Snaps global API object.\n * @param options.ethereum - The Snap's EIP-1193 provider object.\n * @param options.snapId - The id of the snap that will use the created endowments.\n * @param options.endowments - The list of endowments to provide to the snap.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing the Snap's endowments.\n */\nexport function createEndowments({\n snap,\n ethereum,\n snapId,\n endowments,\n notify,\n}: {\n snap: SnapsProvider;\n ethereum: SnapsEthereumProvider;\n snapId: string;\n endowments: string[];\n notify: NotifyFunction;\n}): { endowments: Record<string, unknown>; teardown: () => Promise<void> } {\n const attenuatedEndowments: Record<string, unknown> = {};\n\n // TODO: All endowments should be hardened to prevent covert communication\n // channels. Hardening the returned objects breaks tests elsewhere in the\n // monorepo, so further research is needed.\n const result = endowments.reduce<{\n allEndowments: Record<string, unknown>;\n teardowns: (() => Promise<void> | void)[];\n }>(\n ({ allEndowments, teardowns }, endowmentName) => {\n // First, check if the endowment has a factory, and default to that.\n if (endowmentFactories.has(endowmentName)) {\n if (!hasProperty(attenuatedEndowments, endowmentName)) {\n // Call the endowment factory for the current endowment. If the factory\n // creates multiple endowments, they will all be assigned to the\n // `attenuatedEndowments` object, but will only be passed on to the snap\n // if explicitly listed among its endowment.\n // This may not have an actual use case, but, safety first.\n\n // We just confirmed that endowmentFactories has the specified key.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const { teardownFunction, ...endowment } = endowmentFactories.get(\n endowmentName,\n )!({ sourceLabel: `Snap: ${snapId}`, notify });\n Object.assign(attenuatedEndowments, endowment);\n if (teardownFunction) {\n teardowns.push(teardownFunction);\n }\n }\n allEndowments[endowmentName] = attenuatedEndowments[endowmentName];\n } else if (endowmentName === 'ethereum') {\n // Special case for adding the EIP-1193 provider.\n allEndowments[endowmentName] = ethereum;\n } else if (endowmentName in rootRealmGlobal) {\n logWarning(`Access to unhardened global ${endowmentName}.`);\n // If the endowment doesn't have a factory, just use whatever is on the\n // global object.\n const globalValue = (rootRealmGlobal as Record<string, unknown>)[\n endowmentName\n ];\n allEndowments[endowmentName] = globalValue;\n } else {\n // If we get to this point, we've been passed an endowment that doesn't\n // exist in our current environment.\n throw rpcErrors.internal(`Unknown endowment: \"${endowmentName}\".`);\n }\n return { allEndowments, teardowns };\n },\n {\n allEndowments: { snap },\n teardowns: [],\n },\n );\n\n const teardown = async () => {\n await Promise.all(\n result.teardowns.map(async (teardownFunction) => teardownFunction()),\n );\n };\n return { endowments: result.allEndowments, teardown };\n}\n"]}
|
|
@@ -117,20 +117,21 @@ class AlteredResponse extends Response {
|
|
|
117
117
|
/**
|
|
118
118
|
* Create a network endowment, consisting of a `fetch` function.
|
|
119
119
|
* This allows us to provide a teardown function, so that we can cancel
|
|
120
|
-
* any pending requests, connections, streams, etc. that may be open when
|
|
121
|
-
* is
|
|
120
|
+
* any pending requests, connections, streams, etc. that may be open when the
|
|
121
|
+
* execution context is torn down.
|
|
122
122
|
*
|
|
123
123
|
* This wraps the original implementation of `fetch`,
|
|
124
124
|
* to ensure that a bad actor cannot get access to the original function, thus
|
|
125
125
|
* potentially preventing the network requests from being torn down.
|
|
126
126
|
*
|
|
127
127
|
* @param options - An options bag.
|
|
128
|
-
* @param options.notify - A
|
|
128
|
+
* @param options.notify - A notification callback for outbound request
|
|
129
|
+
* lifecycle events.
|
|
129
130
|
* @returns An object containing a wrapped `fetch`
|
|
130
131
|
* function, as well as a teardown function.
|
|
131
132
|
*/
|
|
132
133
|
const createNetwork = ({ notify } = {}) => {
|
|
133
|
-
(0, utils_1.assert)(notify, '
|
|
134
|
+
(0, utils_1.assert)(notify, 'The "notify" callback is required by the network endowment factory.');
|
|
134
135
|
// Open fetch calls or open body streams
|
|
135
136
|
const openConnections = new Set();
|
|
136
137
|
// Track last teardown count
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.cjs","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport { withTeardown } from '../utils';\n\n/**\n * This class wraps a Response object.\n * That way, a teardown process can stop any processes left.\n */\nexport class ResponseWrapper implements Response {\n readonly #teardownRef: { lastTeardown: number };\n\n readonly #ogResponse: Response;\n\n readonly #onStart: () => Promise<void>;\n\n readonly #onFinish: () => Promise<void>;\n\n constructor(\n ogResponse: Response,\n teardownRef: { lastTeardown: number },\n onStart: () => Promise<void>,\n onFinish: () => Promise<void>,\n ) {\n this.#ogResponse = ogResponse;\n this.#teardownRef = teardownRef;\n this.#onStart = onStart;\n this.#onFinish = onFinish;\n }\n\n get body(): ReadableStream<Uint8Array> | null {\n return this.#ogResponse.body;\n }\n\n get bodyUsed() {\n return this.#ogResponse.bodyUsed;\n }\n\n get headers() {\n return this.#ogResponse.headers;\n }\n\n get ok() {\n return this.#ogResponse.ok;\n }\n\n get redirected() {\n return this.#ogResponse.redirected;\n }\n\n get status() {\n return this.#ogResponse.status;\n }\n\n get statusText() {\n return this.#ogResponse.statusText;\n }\n\n get type() {\n return this.#ogResponse.type;\n }\n\n get url() {\n return this.#ogResponse.url;\n }\n\n async text() {\n return await withTeardown<string>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.text();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n return await withTeardown<ArrayBuffer>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.arrayBuffer();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async blob(): Promise<Blob> {\n return await withTeardown<Blob>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.blob();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n clone(): Response {\n const newResponse = this.#ogResponse.clone();\n return new ResponseWrapper(\n newResponse,\n this.#teardownRef,\n this.#onStart,\n this.#onFinish,\n );\n }\n\n async formData(): Promise<FormData> {\n return await withTeardown<FormData>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.formData();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async json(): Promise<any> {\n return await withTeardown(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.json();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n}\n\n// We redefine the global Response class to overwrite [Symbol.hasInstance].\n// This fixes problems where the response from `fetch` would not pass\n// instance of checks, leading to failures in WASM bindgen.\nclass AlteredResponse extends Response {\n static [Symbol.hasInstance](instance: unknown) {\n return instance instanceof Response || instance instanceof ResponseWrapper;\n }\n}\n\n/**\n * Create a network endowment, consisting of a `fetch` function.\n * This allows us to provide a teardown function, so that we can cancel\n * any pending requests, connections, streams, etc. that may be open when a snap\n * is terminated.\n *\n * This wraps the original implementation of `fetch`,\n * to ensure that a bad actor cannot get access to the original function, thus\n * potentially preventing the network requests from being torn down.\n *\n * @param options - An options bag.\n * @param options.notify - A reference to the notify function of the snap executor.\n * @returns An object containing a wrapped `fetch`\n * function, as well as a teardown function.\n */\nconst createNetwork = ({ notify }: EndowmentFactoryOptions = {}) => {\n assert(notify, 'Notify must be passed to network endowment factory');\n // Open fetch calls or open body streams\n const openConnections = new Set<{ cancel: () => Promise<void> }>();\n // Track last teardown count\n const teardownRef = { lastTeardown: 0 };\n\n // Remove items from openConnections after they were garbage collected\n const cleanup = new FinalizationRegistry<() => void>(\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n (callback) => callback(),\n );\n\n const _fetch: typeof fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const abortController = new AbortController();\n if (init?.signal !== null && init?.signal !== undefined) {\n const originalSignal = init.signal;\n // Merge abort controllers\n originalSignal.addEventListener(\n 'abort',\n () => {\n abortController.abort((originalSignal as any).reason);\n },\n { once: true },\n );\n }\n\n let started = false;\n const onStart = async () => {\n if (!started) {\n started = true;\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n }\n };\n\n let finished = false;\n const onFinish = async () => {\n if (!finished) {\n finished = true;\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n };\n\n let res: Response;\n let openFetchConnection: { cancel: () => Promise<void> } | undefined;\n return await withTeardown(\n (async () => {\n try {\n const fetchPromise = fetch(input, {\n ...init,\n signal: abortController.signal,\n });\n\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n\n openFetchConnection = {\n cancel: async () => {\n abortController.abort();\n try {\n await fetchPromise;\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openFetchConnection);\n\n res = new ResponseWrapper(\n await fetchPromise,\n teardownRef,\n onStart,\n onFinish,\n );\n } finally {\n if (openFetchConnection !== undefined) {\n openConnections.delete(openFetchConnection);\n }\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n\n if (res.body !== null) {\n const body = new WeakRef<ReadableStream>(res.body);\n\n const openBodyConnection = {\n cancel:\n /* istanbul ignore next: see it.todo('can be torn down during body read') test */\n async () => {\n try {\n await body.deref()?.cancel();\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openBodyConnection);\n cleanup.register(\n res.body,\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n () => openConnections.delete(openBodyConnection),\n );\n }\n return harden(res);\n })(),\n teardownRef,\n );\n };\n\n const teardownFunction = async () => {\n teardownRef.lastTeardown += 1;\n const promises: Promise<void>[] = [];\n openConnections.forEach(({ cancel }) => promises.push(cancel()));\n openConnections.clear();\n await Promise.all(promises);\n };\n\n return {\n fetch: harden(_fetch),\n // Request, Headers and Response are the endowments injected alongside fetch\n // only when 'endowment:network-access' permission is requested,\n // therefore these are hardened as part of fetch dependency injection within its factory.\n // These endowments are not (and should never be) available by default.\n Request: harden(Request),\n Headers: harden(Headers),\n Response: harden(AlteredResponse),\n teardownFunction,\n };\n};\n\nconst endowmentModule = {\n names: ['fetch', 'Request', 'Headers', 'Response'] as const,\n factory: createNetwork,\n};\nexport default endowmentModule;\n"]}
|
|
1
|
+
{"version":3,"file":"network.cjs","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type { EndowmentFactoryOptions } from './commonEndowmentFactory';\nimport { withTeardown } from '../utils';\n\n/**\n * This class wraps a Response object.\n * That way, a teardown process can stop any processes left.\n */\nexport class ResponseWrapper implements Response {\n readonly #teardownRef: { lastTeardown: number };\n\n readonly #ogResponse: Response;\n\n readonly #onStart: () => Promise<void>;\n\n readonly #onFinish: () => Promise<void>;\n\n constructor(\n ogResponse: Response,\n teardownRef: { lastTeardown: number },\n onStart: () => Promise<void>,\n onFinish: () => Promise<void>,\n ) {\n this.#ogResponse = ogResponse;\n this.#teardownRef = teardownRef;\n this.#onStart = onStart;\n this.#onFinish = onFinish;\n }\n\n get body(): ReadableStream<Uint8Array> | null {\n return this.#ogResponse.body;\n }\n\n get bodyUsed() {\n return this.#ogResponse.bodyUsed;\n }\n\n get headers() {\n return this.#ogResponse.headers;\n }\n\n get ok() {\n return this.#ogResponse.ok;\n }\n\n get redirected() {\n return this.#ogResponse.redirected;\n }\n\n get status() {\n return this.#ogResponse.status;\n }\n\n get statusText() {\n return this.#ogResponse.statusText;\n }\n\n get type() {\n return this.#ogResponse.type;\n }\n\n get url() {\n return this.#ogResponse.url;\n }\n\n async text() {\n return await withTeardown<string>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.text();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async arrayBuffer(): Promise<ArrayBuffer> {\n return await withTeardown<ArrayBuffer>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.arrayBuffer();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async blob(): Promise<Blob> {\n return await withTeardown<Blob>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.blob();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n clone(): Response {\n const newResponse = this.#ogResponse.clone();\n return new ResponseWrapper(\n newResponse,\n this.#teardownRef,\n this.#onStart,\n this.#onFinish,\n );\n }\n\n async formData(): Promise<FormData> {\n return await withTeardown<FormData>(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.formData();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n\n async json(): Promise<any> {\n return await withTeardown(\n (async () => {\n await this.#onStart();\n try {\n return await this.#ogResponse.json();\n } finally {\n await this.#onFinish();\n }\n })(),\n this.#teardownRef,\n );\n }\n}\n\n// We redefine the global Response class to overwrite [Symbol.hasInstance].\n// This fixes problems where the response from `fetch` would not pass\n// instance of checks, leading to failures in WASM bindgen.\nclass AlteredResponse extends Response {\n static [Symbol.hasInstance](instance: unknown) {\n return instance instanceof Response || instance instanceof ResponseWrapper;\n }\n}\n\n/**\n * Create a network endowment, consisting of a `fetch` function.\n * This allows us to provide a teardown function, so that we can cancel\n * any pending requests, connections, streams, etc. that may be open when the\n * execution context is torn down.\n *\n * This wraps the original implementation of `fetch`,\n * to ensure that a bad actor cannot get access to the original function, thus\n * potentially preventing the network requests from being torn down.\n *\n * @param options - An options bag.\n * @param options.notify - A notification callback for outbound request\n * lifecycle events.\n * @returns An object containing a wrapped `fetch`\n * function, as well as a teardown function.\n */\nconst createNetwork = ({ notify }: EndowmentFactoryOptions = {}) => {\n assert(\n notify,\n 'The \"notify\" callback is required by the network endowment factory.',\n );\n // Open fetch calls or open body streams\n const openConnections = new Set<{ cancel: () => Promise<void> }>();\n // Track last teardown count\n const teardownRef = { lastTeardown: 0 };\n\n // Remove items from openConnections after they were garbage collected\n const cleanup = new FinalizationRegistry<() => void>(\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n (callback) => callback(),\n );\n\n const _fetch: typeof fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const abortController = new AbortController();\n if (init?.signal !== null && init?.signal !== undefined) {\n const originalSignal = init.signal;\n // Merge abort controllers\n originalSignal.addEventListener(\n 'abort',\n () => {\n abortController.abort((originalSignal as any).reason);\n },\n { once: true },\n );\n }\n\n let started = false;\n const onStart = async () => {\n if (!started) {\n started = true;\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n }\n };\n\n let finished = false;\n const onFinish = async () => {\n if (!finished) {\n finished = true;\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n };\n\n let res: Response;\n let openFetchConnection: { cancel: () => Promise<void> } | undefined;\n return await withTeardown(\n (async () => {\n try {\n const fetchPromise = fetch(input, {\n ...init,\n signal: abortController.signal,\n });\n\n await notify({\n method: 'OutboundRequest',\n params: { source: 'fetch' },\n });\n\n openFetchConnection = {\n cancel: async () => {\n abortController.abort();\n try {\n await fetchPromise;\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openFetchConnection);\n\n res = new ResponseWrapper(\n await fetchPromise,\n teardownRef,\n onStart,\n onFinish,\n );\n } finally {\n if (openFetchConnection !== undefined) {\n openConnections.delete(openFetchConnection);\n }\n await notify({\n method: 'OutboundResponse',\n params: { source: 'fetch' },\n });\n }\n\n if (res.body !== null) {\n const body = new WeakRef<ReadableStream>(res.body);\n\n const openBodyConnection = {\n cancel:\n /* istanbul ignore next: see it.todo('can be torn down during body read') test */\n async () => {\n try {\n await body.deref()?.cancel();\n } catch {\n /* do nothing */\n }\n },\n };\n openConnections.add(openBodyConnection);\n cleanup.register(\n res.body,\n /* istanbul ignore next: can't test garbage collection without modifying node parameters */\n () => openConnections.delete(openBodyConnection),\n );\n }\n return harden(res);\n })(),\n teardownRef,\n );\n };\n\n const teardownFunction = async () => {\n teardownRef.lastTeardown += 1;\n const promises: Promise<void>[] = [];\n openConnections.forEach(({ cancel }) => promises.push(cancel()));\n openConnections.clear();\n await Promise.all(promises);\n };\n\n return {\n fetch: harden(_fetch),\n // Request, Headers and Response are the endowments injected alongside fetch\n // only when 'endowment:network-access' permission is requested,\n // therefore these are hardened as part of fetch dependency injection within its factory.\n // These endowments are not (and should never be) available by default.\n Request: harden(Request),\n Headers: harden(Headers),\n Response: harden(AlteredResponse),\n teardownFunction,\n };\n};\n\nconst endowmentModule = {\n names: ['fetch', 'Request', 'Headers', 'Response'] as const,\n factory: createNetwork,\n};\nexport default endowmentModule;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ;;gBAU5C,UAAU,EAAE,QAAQ,EACpB,WAAW,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,EACrC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAQ/B,IAAI,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAE5C;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,OAAO,YAEV;IAED,IAAI,EAAE,YAEL;IAED,IAAI,UAAU,YAEb;IAED,IAAI,MAAM,WAET;IAED,IAAI,UAAU,WAEb;IAED,IAAI,IAAI,iBAEP;IAED,IAAI,GAAG,WAEN;IAEK,IAAI;IAcJ,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAcnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,KAAK,IAAI,QAAQ;IAUX,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAc7B,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;CAa3B;AAKD,cAAM,eAAgB,SAAQ,QAAQ;IACpC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,OAAO;CAG9C;
|
|
1
|
+
{"version":3,"file":"network.d.cts","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ;;gBAU5C,UAAU,EAAE,QAAQ,EACpB,WAAW,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,EACrC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAQ/B,IAAI,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAE5C;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,OAAO,YAEV;IAED,IAAI,EAAE,YAEL;IAED,IAAI,UAAU,YAEb;IAED,IAAI,MAAM,WAET;IAED,IAAI,UAAU,WAEb;IAED,IAAI,IAAI,iBAEP;IAED,IAAI,GAAG,WAEN;IAEK,IAAI;IAcJ,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAcnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,KAAK,IAAI,QAAQ;IAUX,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAc7B,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;CAa3B;AAKD,cAAM,eAAgB,SAAQ,QAAQ;IACpC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,OAAO;CAG9C;AAoKD,QAAA,MAAM,eAAe;;2BAlJc,uBAAuB;;;;;;;;;;;;;CAqJzD,CAAC;AACF,eAAe,eAAe,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ;;gBAU5C,UAAU,EAAE,QAAQ,EACpB,WAAW,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,EACrC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAQ/B,IAAI,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAE5C;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,OAAO,YAEV;IAED,IAAI,EAAE,YAEL;IAED,IAAI,UAAU,YAEb;IAED,IAAI,MAAM,WAET;IAED,IAAI,UAAU,WAEb;IAED,IAAI,IAAI,iBAEP;IAED,IAAI,GAAG,WAEN;IAEK,IAAI;IAcJ,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAcnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,KAAK,IAAI,QAAQ;IAUX,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAc7B,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;CAa3B;AAKD,cAAM,eAAgB,SAAQ,QAAQ;IACpC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,OAAO;CAG9C;
|
|
1
|
+
{"version":3,"file":"network.d.mts","sourceRoot":"","sources":["../../../src/common/endowments/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qCAAiC;AAGxE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,QAAQ;;gBAU5C,UAAU,EAAE,QAAQ,EACpB,WAAW,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,EACrC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC;IAQ/B,IAAI,IAAI,IAAI,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAE5C;IAED,IAAI,QAAQ,YAEX;IAED,IAAI,OAAO,YAEV;IAED,IAAI,EAAE,YAEL;IAED,IAAI,UAAU,YAEb;IAED,IAAI,MAAM,WAET;IAED,IAAI,UAAU,WAEb;IAED,IAAI,IAAI,iBAEP;IAED,IAAI,GAAG,WAEN;IAEK,IAAI;IAcJ,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAcnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,KAAK,IAAI,QAAQ;IAUX,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IAc7B,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC;CAa3B;AAKD,cAAM,eAAgB,SAAQ,QAAQ;IACpC,MAAM,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,OAAO;CAG9C;AAoKD,QAAA,MAAM,eAAe;;2BAlJc,uBAAuB;;;;;;;;;;;;;CAqJzD,CAAC;AACF,eAAe,eAAe,CAAC"}
|
|
@@ -113,20 +113,21 @@ class AlteredResponse extends Response {
|
|
|
113
113
|
/**
|
|
114
114
|
* Create a network endowment, consisting of a `fetch` function.
|
|
115
115
|
* This allows us to provide a teardown function, so that we can cancel
|
|
116
|
-
* any pending requests, connections, streams, etc. that may be open when
|
|
117
|
-
* is
|
|
116
|
+
* any pending requests, connections, streams, etc. that may be open when the
|
|
117
|
+
* execution context is torn down.
|
|
118
118
|
*
|
|
119
119
|
* This wraps the original implementation of `fetch`,
|
|
120
120
|
* to ensure that a bad actor cannot get access to the original function, thus
|
|
121
121
|
* potentially preventing the network requests from being torn down.
|
|
122
122
|
*
|
|
123
123
|
* @param options - An options bag.
|
|
124
|
-
* @param options.notify - A
|
|
124
|
+
* @param options.notify - A notification callback for outbound request
|
|
125
|
+
* lifecycle events.
|
|
125
126
|
* @returns An object containing a wrapped `fetch`
|
|
126
127
|
* function, as well as a teardown function.
|
|
127
128
|
*/
|
|
128
129
|
const createNetwork = ({ notify } = {}) => {
|
|
129
|
-
assert(notify, '
|
|
130
|
+
assert(notify, 'The "notify" callback is required by the network endowment factory.');
|
|
130
131
|
// Open fetch calls or open body streams
|
|
131
132
|
const openConnections = new Set();
|
|
132
133
|
// Track last teardown count
|