@endo/eventual-send
Advanced tools
Comparing version 0.15.5 to 0.16.0
@@ -6,2 +6,16 @@ # Change Log | ||
## [0.16.0](https://github.com/endojs/endo/compare/@endo/eventual-send@0.15.5...@endo/eventual-send@0.16.0) (2022-08-23) | ||
### ⚠ BREAKING CHANGES | ||
* **eventual-send:** Disallow using E proxy methods as functions (#1255) | ||
### Bug Fixes | ||
* **eventual-send:** Disallow using E proxy methods as functions ([#1255](https://github.com/endojs/endo/issues/1255)) ([43b7962](https://github.com/endojs/endo/commit/43b796232634b54c9e7de1c0a2349d22c29fc384)) | ||
* typedef default onfulfilled handler for E.when ([c5582ca](https://github.com/endojs/endo/commit/c5582ca7473e0a5d94ef4753ff54e0626cdb1d0a)) | ||
### [0.15.5](https://github.com/endojs/endo/compare/@endo/eventual-send@0.15.4...@endo/eventual-send@0.15.5) (2022-06-28) | ||
@@ -8,0 +22,0 @@ |
{ | ||
"name": "@endo/eventual-send", | ||
"version": "0.15.5", | ||
"version": "0.16.0", | ||
"description": "Extend a Promise class to implement the eventual-send API", | ||
@@ -30,4 +30,4 @@ "type": "module", | ||
"devDependencies": { | ||
"@endo/lockdown": "^0.1.15", | ||
"@endo/ses-ava": "^0.2.27", | ||
"@endo/lockdown": "^0.1.16", | ||
"@endo/ses-ava": "^0.2.28", | ||
"ava": "^3.12.1", | ||
@@ -66,3 +66,3 @@ "c8": "^7.7.3", | ||
}, | ||
"gitHead": "a311acb02115271fbda6953734d0b4f52aa85892" | ||
"gitHead": "7dc29059b201826295cbf2deb28bb2ed70f5ec1f" | ||
} |
60
src/E.js
@@ -6,2 +6,4 @@ // @ts-check | ||
const { details: X, quote: q } = assert; | ||
/** @type {ProxyHandler<any>} */ | ||
@@ -23,2 +25,11 @@ const baseFreezableProxyHandler = { | ||
// E Proxy handlers pretend that any property exists on the target and returns | ||
// a function for their value. While this function is "bound" by context, it is | ||
// meant to be called as a method. For that reason, the returned function | ||
// includes a check that the `this` argument corresponds to the initial | ||
// receiver when the function was retrieved. | ||
// E Proxy handlers also forward direct calls to the target in case the remote | ||
// is a function instead of an object. No such receiver checks are necessary in | ||
// that case. | ||
/** | ||
@@ -34,4 +45,24 @@ * A Proxy handler for E(x). | ||
...baseFreezableProxyHandler, | ||
get(_target, p, _receiver) { | ||
return harden((...args) => HandledPromise.applyMethod(x, p, args)); | ||
get(_target, p, receiver) { | ||
return harden( | ||
{ | ||
// This function purposely checks the `this` value (see above) | ||
// In order to be `this` sensitive it is defined using concise method | ||
// syntax rather than as an arrow function. To ensure the function | ||
// is not constructable, it also avoids the `function` syntax. | ||
[p](...args) { | ||
if (this !== receiver) { | ||
// Reject the async function call | ||
return HandledPromise.reject( | ||
assert.error( | ||
X`Unexpected receiver for "${p}" method of E(${q(x)})`, | ||
), | ||
); | ||
} | ||
return HandledPromise.applyMethod(x, p, args); | ||
}, | ||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/50319 | ||
}[p], | ||
); | ||
}, | ||
@@ -59,7 +90,22 @@ apply(_target, _thisArg, argArray = []) { | ||
...baseFreezableProxyHandler, | ||
get(_target, p, _receiver) { | ||
return (...args) => { | ||
HandledPromise.applyMethodSendOnly(x, p, args); | ||
return undefined; | ||
}; | ||
get(_target, p, receiver) { | ||
return harden( | ||
{ | ||
// This function purposely checks the `this` value (see above) | ||
// In order to be `this` sensitive it is defined using concise method | ||
// syntax rather than as an arrow function. To ensure the function | ||
// is not constructable, it also avoids the `function` syntax. | ||
[p](...args) { | ||
// Throw since the function returns nothing | ||
assert.equal( | ||
this, | ||
receiver, | ||
X`Unexpected receiver for "${p}" method of E.sendOnly(${q(x)})`, | ||
); | ||
HandledPromise.applyMethodSendOnly(x, p, args); | ||
return undefined; | ||
}, | ||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/50319 | ||
}[p], | ||
); | ||
}, | ||
@@ -66,0 +112,0 @@ apply(_target, _thisArg, argsArray = []) { |
@@ -260,3 +260,3 @@ // Type definitions for eventual-send | ||
*/ | ||
readonly when: <T, U>( | ||
readonly when: <T, U = Awaited<T>>( | ||
x: T, | ||
@@ -263,0 +263,0 @@ onfulfilled?: (value: Awaited<T>) => ERef<U>, |
@@ -49,1 +49,24 @@ /* eslint-disable @endo/no-polymorphic-call, import/no-extraneous-dependencies, no-restricted-globals, prettier/prettier */ | ||
}; | ||
// when | ||
const aPromise = Promise.resolve('a'); | ||
const onePromise = Promise.resolve(1); | ||
const remoteString: ERef<string> = Promise.resolve('remote'); | ||
E.when(Promise.all([aPromise, onePromise, remoteString])).then( | ||
([str, num, remote]) => { | ||
expectType<string>(str); | ||
expectType<number>(num); | ||
expectType<string>(remote); | ||
}, | ||
); | ||
E.when( | ||
Promise.all([aPromise, onePromise, remoteString]), | ||
([str, num, remote]) => { | ||
expectType<string>(str); | ||
expectType<number>(num); | ||
expectType<string>(remote); | ||
return { something: 'new' }; | ||
}, | ||
).then(result => { | ||
expectType<{ something: string }>(result); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
84967
1212