Scripting API Revamp #2292
Replies: 8 comments 2 replies
-
@AndrewBastin there should be a way to manipulate the request before sending. For example postman has |
Beta Was this translation helpful? Give feedback.
-
This file mentioned in readme is actually missing: Try out the demo src/demo.ts using:
|
Beta Was this translation helpful? Give feedback.
-
Requesting comments on improving scripting DX. First would be having a js context that has a lifetime from start of request to end of request. We could write one script instead of having separate scripts for prerequest and testing scripts. Also users wont have to learn a new thing called shared api since they can store stuff in regular variables. This has popular precedent in browser js scripting in attaching handlers to events. We could try to do type definitions for pw.env.set("var", "foo")
console.log('before request')
let x = null
onRequest( request => {
request.header = 'foo'
x = 'foo' // No need of shared api
request.get.date = Date.timestamp()
console.log('request changed', request)
})
onResponse( response => {
expect(response.code).toBe(200) // No test block
test("expecting stuff", () => {
expect(response.code).toBe(200)
expect(response.body.place).toBe(x)
})
// mean is defined in another global script
console.log('average temp', mean(response.json.temperatures))
})
Second would be cascading scripts. We can define a global script which is evaluated before each request script. This also has strong popular precedent in browser js scripting. //global.js
function foo() {}
//perRequest.js
foo() |
Beta Was this translation helpful? Give feedback.
-
Any news on this? Seems to have gotten stale. |
Beta Was this translation helpful? Give feedback.
-
Any update on this? |
Beta Was this translation helpful? Give feedback.
-
Bumping this - Would love to be able to use |
Beta Was this translation helpful? Give feedback.
-
Yep, this is sadly still a blocker for us, we would love to be able to migrate to hoppscotch but we rely on heavy use of scripting to automate rather annoying authentication flows. |
Beta Was this translation helpful? Give feedback.
-
Looks like silence seems to be the communication strategy for Hoppscotch. People asking right and left, yet no response. Very professional. |
Beta Was this translation helpful? Give feedback.
-
RFC: Scripting API revamp
This is the first time we are doing an RFC (Request for Comments) here at Hoppscotch but due to the need for us needing to get this right hopefully in a single iteration itself and there are a lot of opinions on what should be added to the Hoppscotch Scripting API, hence we are introducing this discussion (which hopefully will turn into a tradition).
Summary
Hoppscotch has a strict WASM-based JavaScript Sandbox in which all of the user-defined scripts (pre-request scripts and test scripts) are executed. The main reason why such a sandbox is enforced is to actually allow for a really strong security story and to reduce the possibilities of leaking access into sensitive information over the sandbox or even privilege escalation (in the context of evaluating page scripts).
The current implementation of the sandbox features a set of APIs under the
pw
namespace (where pw refers to Postwoman, the previous name of Hoppscotch). The pre-request scripts feature anenv
API for reading and writing environment variables and the test scripts feature the testing API (test
and the fluentexpect
API for assertions) along with the aforementionedenv
API to facilitate making test scripts.The above APIs haven’t changed much over time and have stayed pretty much the same, the only recently made change is to the
env
API where they can now do recursive environment resolution. But over time we have gotten several feature requests to improve the capabilities of these scripts. These are:Along with similar discussions in pre-request and test scripts to support different use cases and APIs. This RFC plans to propose a solution for most of the issues defined here and some revamp to some of the existing APIs. Along with the introduction of a revamped
hopp
namespace with much cleaner and better APIs.Goals of the RFC
With the revamp of the sandbox, we are tackling the following technical goals.
esm.sh
)console
(see below point about Console implementation)btoa
andatob
crypto
fetch
andXMLHTTPRequest
setTimeout
andsetInterval
console.log
(and friends’) calls are rendered while trying to preserve as much functionality as offered by DevTools. (mostly object logging and string logging, we are not planning for things like coloring and CSS support within logs).env
API.artifact
which allows processing and transformation to be applied to responses which can then be exported after script execution.shared
API.pw
namespace to thehopp
namespace.Changes in detail
TypeScript based code completion and linting
Currently, we use Tern for code completion suggestions and linting support. Tern has worked well but compared to other code analysis tools available to us right now, it lacks the intuitiveness and capabilities. Hence, we will be using a TypeScript-based intelligence service running as a web worker to run the code completion engine. We are planning to leverage the work put forward by the Monaco Editor and its implementation of the TypeScript language services and try to recreate that in our code editor of choice, CodeMirror. This does not mean the scripts will be written in TypeScript. The scripts will continue as JS files (no type annotations and TypeScript exclusive stuff allowed), but the intelligence will be powered by the TypeScript language service. You can still improve type checking by using JSDoc Types similar to how it works for a JS file with the TypeScript compiler.
Proper handling of scheduled tasks and task queues
The sandbox will now properly handle scheduled JS tasks (created by things like the
setInterval
andsetTimeout
APIs) and wait for their completion before marking the script execution is complete.Deprecation of the
pw
namespaceWe are going to be marking the
pw
namespace as deprecated and will mark warnings when those APIs are used. Thepw
namespace will not receive any more future features that will be coming to the scripting APIs and will stay frozen in time the way it is in the present. Hence, none of the below-proposed changes introduced by this RFC will also make it to thepw
namespace.ESM Module Loading
We are planning to introduce ESM Module loading to the scripts. Since scripts do not deal with a file structure, this doesn’t make a lot of sense on its own. But we along with ESM Module import support we will be allowing remote URLs as module identifiers. This helps us deal with a long-standing issue with scripts where external libraries (like NPM libraries) can’t be used within the sandbox. With the revamp, users will be able to import modules from sources like Skypack, esm.sh, and other similar sources which provide ESM modules.
It is up to the user to be aware of the limitations of the library (what APIs the library uses etc.) and whether it will work with the sandbox environment (if it just uses the standard JS objects and APIs, it should be fine) and also worry about versioning and reliability of the actual source of the module. The sandbox will deal with fetching and loading it into the environment and we are not planning any security measures for this right now (although I would love to discuss this over here).
More Compatibility with the Standard JS objects and APIs
Many more of the standard APIs that are not implemented by the sandbox will be implemented with this RFC implementation. Notably some of the requested APIs like
crypto
,console
,atob
/btoa
, and many more. This also helps with the ESM Module Loading story as more standard library integrations mean stronger compatibility with the library ecosystem.Sandbox Console Implementation
Funnily enough, the sandbox currently doesn’t support the
console
API for logging things into a console for debugging purposes. This is a design oversight that should have been tackled early itself, the community has come up with really interesting solutions to this which are undoubtedly really hacky and not exactly recommended. Hence, this iteration will bring a subset of theconsole
API to the sandbox environment. Currently in plans areconsole.log
,console.warn
,console.error
andconsole.debug
. One thing to note though is that we are not planning to support console coloring and styling which is present in the DevTools logging. We do want to implement the rest of the APIs as well and we want to allow for other remaining APIs in the console to be implemented as well, but we are not sure if they are worth the effort right now and can be added later on. (please do let me know in the discussion below if this is needed by you).Artifact API
The Artifact API (
hopp.artifact
) is a solution to the problem given in issue #1745. This allows for the scripts (this will be available to both test and pre-request scripts) to process the response in a certain way and be able to export that processed value as a file that could then be downloaded. The implementation of the API will have 4 main functions.hopp.artifact.create(key: string, value: string)
- Creates an artifacthopp.artifact.update(key: string, newValue: string)
- Updates an artifacthopp.artifact.get(key: string)
- Gets an artifacthopp.artifact.delete(key: string)
- Deletes an artifactThe API will only take strings as of right now, but if wanted (please let me know below), we can allow for binary data as well. The reason why we are not considering binary right now is considering the marshaling cost of moving the data in and out of the sandbox especially if the data is really big.
Shared API
The Shared API (
hopp.shared
) is also a really simple API like the Artifact API, but it is more for storing ephemeral states that should be transferred between pre-request and test scripts, previously users resorted to using theenv
API to pass the data along which isn’t ideal. The API surface is basically the same as the Artifact API, but it can take any value that can be serialized to JSON (due to some marshaling restrictions).Updates to the
env
APIWe are working towards improving the
env
API to allow for more capabilities for managing environments.env
API will now featurehopp.env.active
andhopp.env.global
which will have operations within it that will allow you to query specifically within the selected and the global environments (eg.hopp.env.active.get("username")
will give you the value within the selected environment and ignore the global environment.). The previous way of doinghopp.env.get
and so on will still maintain the current behavior and still look at both global and selected together.hopp.env.delete
operation can be used to delete an environment variable. If multiple declarations are present, the highest precedence version of the variable will be deleted.<<x>>
with its value at that point). These are currently available to scripts withpw.env.getResolve
and friends. We are going to now makehopp.env.get
by default do recursive resolution, to allow to opt-out of the recursive resolution, we will be introducinghopp.env.getRaw
which will give out the raw value of the environment variable.Final Notes
This is what we have in mind as a roadmap for a better scripting experience for Hoppscotch, a lot of this is to improve the capabilities meanwhile still keeping the security and predictability of the feature. This implementation will not be sudden but a slow process that spans into the next couple of months and some of the above-defined improvements may be deferred or dropped if we encounter any technical limitations or other constraints.
As I have mentioned in the beginning, we want to open up the discourse to improving the scripting experience, if you have any suggestions or certain pain points we haven’t addressed above, please join in below on the discussion.
Beta Was this translation helpful? Give feedback.
All reactions