Skip to content

Commit 1e089e6

Browse files
committed
Move require implementation to pm-require.js
1 parent 9a426d2 commit 1e089e6

File tree

3 files changed

+70
-66
lines changed

3 files changed

+70
-66
lines changed

lib/sandbox/execute.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const _ = require('lodash'),
99
PostmanTimers = require('./timers'),
1010
PostmanAPI = require('./pmapi'),
1111
PostmanCookieStore = require('./cookie-store'),
12-
PostmanRequireStore = require('./pm-require'),
12+
createPostmanRequire = require('./pm-require'),
1313

1414
EXECUTION_RESULT_EVENT_BASE = 'execution.result.',
1515
EXECUTION_REQUEST_EVENT_BASE = 'execution.request.',
@@ -229,8 +229,7 @@ module.exports = function (bridge, glob) {
229229
},
230230
dispatchAssertions,
231231
new PostmanCookieStore(id, bridge, timers),
232-
new PostmanRequireStore(options.requireFileResolver),
233-
scope,
232+
createPostmanRequire(options.requireFileResolver, scope),
234233
{
235234
disabledAPIs: initializationOptions.disabledAPIs
236235
})

lib/sandbox/pm-require.js

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
const MODULE_KEY = '__module_obj', // why not use `module`?
2+
MODULE_WRAPPER = [
3+
'(function (exports, module) {\n',
4+
`\n})(${MODULE_KEY}.exports, ${MODULE_KEY});`
5+
];
6+
17
class PostmanRequireStore {
28
constructor (fileCache) {
39
this.fileCache = fileCache || {};
@@ -18,4 +24,62 @@ class PostmanRequireStore {
1824
}
1925
}
2026

21-
module.exports = PostmanRequireStore;
27+
function createPostmanRequire (fileCache, scope) {
28+
const store = new PostmanRequireStore(fileCache);
29+
30+
return function require (name) {
31+
const path = store.getResolvedPath(name);
32+
33+
this.cache = this.cache || {};
34+
35+
// Always use the resolved path as the ID of the module. This
36+
// ensures that relative paths are handled correctly.
37+
if (this.cache[path]) {
38+
return this.cache[path].exports;
39+
}
40+
41+
const file = path && store.getFileData(path);
42+
43+
if (!file) {
44+
// Error should contain the name exactly as the user specified.
45+
throw new Error(`Cannot find module '${name}'`);
46+
}
47+
48+
const moduleObj = {
49+
id: path,
50+
exports: {}
51+
};
52+
53+
// Add to cache before executing. This ensures that any dependency
54+
// that tries to import it's parent/ancestor gets the cached
55+
// version and not end up in infinite loop.
56+
this.cache[moduleObj.id] = moduleObj;
57+
58+
const wrappedModule = MODULE_WRAPPER[0] + file + MODULE_WRAPPER[1];
59+
60+
scope.import({
61+
[MODULE_KEY]: moduleObj
62+
});
63+
64+
// Note: We're executing the code in the same scope as the one
65+
// which called the `pm.require` function. This is because we want
66+
// to share the global scope across all the required modules. Any
67+
// locals are available inside the required modules and any locals
68+
// created inside the required modules are available to the parent.
69+
//
70+
// Why `async` = true?
71+
// - We want to allow execution of async code like setTimeout etc.
72+
scope.exec(wrappedModule, true, (err) => {
73+
// Bubble up the error to be caught as execution error
74+
if (err) {
75+
throw err;
76+
}
77+
});
78+
79+
scope.unset(MODULE_KEY);
80+
81+
return moduleObj.exports;
82+
};
83+
}
84+
85+
module.exports = createPostmanRequire;

lib/sandbox/pmapi.js

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ const _ = require('lodash'),
77
PostmanCookieList = sdk.CookieList,
88
chai = require('chai'),
99

10-
MODULE_KEY = '__module_obj', // why not use `module`?
11-
MODULE_WRAPPER = [
12-
'(function (exports, module) {\n',
13-
`\n})(${MODULE_KEY}.exports, ${MODULE_KEY});`
14-
],
15-
1610
/**
1711
* Use this function to assign readonly properties to an object
1812
*
@@ -53,12 +47,11 @@ const _ = require('lodash'),
5347
* @param {Function} onSkipRequest - callback to execute when pm.execution.skipRequest() called
5448
* @param {Function} onAssertion - callback to execute when pm.expect() called
5549
* @param {Object} cookieStore - cookie store
56-
* @param {Object} requireStore - require store
57-
* @param {Object} scope - scope
50+
* @param {Function} require - require
5851
* @param {Object} [options] - options
5952
* @param {Array.<String>} [options.disabledAPIs] - list of disabled APIs
6053
*/
61-
function Postman (execution, onRequest, onSkipRequest, onAssertion, cookieStore, requireStore, scope, options = {}) {
54+
function Postman (execution, onRequest, onSkipRequest, onAssertion, cookieStore, require, options = {}) {
6255
// @todo - ensure runtime passes data in a scope format
6356
let iterationData = new VariableScope();
6457

@@ -301,59 +294,7 @@ function Postman (execution, onRequest, onSkipRequest, onAssertion, cookieStore,
301294
})
302295
},
303296

304-
require: function require (name) {
305-
const path = requireStore.getResolvedPath(name);
306-
307-
this.cache = this.cache || {};
308-
309-
// Always use the resolved path as the ID of the module. This
310-
// ensures that relative paths are handled correctly.
311-
if (this.cache[path]) {
312-
return this.cache[path].exports;
313-
}
314-
315-
const file = path && requireStore.getFileData(path);
316-
317-
if (!file) {
318-
// Error should contain the name exactly as the user specified.
319-
throw new Error(`Cannot find module '${name}'`);
320-
}
321-
322-
const moduleObj = {
323-
id: path,
324-
exports: {}
325-
};
326-
327-
// Add to cache before executing. This ensures that any dependency
328-
// that tries to import it's parent/ancestor gets the cached
329-
// version and not end up in infinite loop.
330-
this.cache[moduleObj.id] = moduleObj;
331-
332-
const wrappedModule = MODULE_WRAPPER[0] + file + MODULE_WRAPPER[1];
333-
334-
scope.import({
335-
[MODULE_KEY]: moduleObj
336-
});
337-
338-
// Note: We're executing the code in the same scope as the one
339-
// which called the `pm.require` function. This is because we want
340-
// to share the global scope across all the required modules. Any
341-
// locals are available inside the required modules and any locals
342-
// created inside the required modules are available to the parent.
343-
//
344-
// Why `async` = true?
345-
// - We want to allow execution of async code like setTimeout etc.
346-
scope.exec(wrappedModule, true, (err) => {
347-
// Bubble up the error to be caught as execution error
348-
if (err) {
349-
throw err;
350-
}
351-
});
352-
353-
scope.unset(MODULE_KEY);
354-
355-
return moduleObj.exports;
356-
}
297+
require: require
357298
}, options.disabledAPIs);
358299

359300
// extend pm api with test runner abilities

0 commit comments

Comments
 (0)