Skip to content

Commit 34dd7b7

Browse files
authored
feat: node paths (#64)
1 parent 18cd963 commit 34dd7b7

5 files changed

Lines changed: 32 additions & 8 deletions

File tree

src/compile/build.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const MINIFY = (() => {
1212
}
1313
})()
1414

15-
module.exports = ({ content, cwd }) =>
15+
module.exports = ({ content, cwd, nodePaths = [] }) =>
1616
esbuild.build({
1717
stdin: {
1818
contents: content,
@@ -24,5 +24,6 @@ module.exports = ({ content, cwd }) =>
2424
platform: 'node',
2525
legalComments: 'eof',
2626
target: 'node24',
27+
nodePaths,
2728
...MINIFY
2829
})

src/compile/index.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22

3-
const { mkdirSync } = require('fs')
3+
const { mkdirSync, readFileSync } = require('fs')
44
const path = require('path')
55

66
const transformDependencies = require('./transform-dependencies')
@@ -24,22 +24,40 @@ const enqueueInstall = (tmpdir, dependencies, allow) => {
2424
return next
2525
}
2626

27-
module.exports = async (snippet, { tmpdir = DEFAULT_TMPDIR, allow = {} } = {}) => {
27+
module.exports = async (snippet, { tmpdir = DEFAULT_TMPDIR, allow = {}, nodePaths = [] } = {}) => {
2828
let content = template(snippet)
2929
const phases = { install: 0 }
3030

31-
const dependencies = detectDependencies(content)
31+
const allDependencies = detectDependencies(content)
32+
installDependencies.validateDependencies(allDependencies, allow.dependencies)
33+
const dependencies = nodePaths.length
34+
? allDependencies.filter(dep => {
35+
const name = installDependencies.extractPackageName(dep)
36+
const version = dep.slice(name.length + 1)
37+
try {
38+
const pkgPath = require.resolve(path.join(name, 'package.json'), { paths: nodePaths })
39+
if (version === 'latest') return false
40+
return JSON.parse(readFileSync(pkgPath, 'utf8')).version !== version
41+
} catch {
42+
return true
43+
}
44+
})
45+
: allDependencies
46+
3247
if (dependencies.length) {
3348
content = transformDependencies(content)
3449
mkdirSync(tmpdir, { recursive: true })
3550
const elapsed = timeSpan()
3651
await enqueueInstall(tmpdir, dependencies, allow)
3752
phases.install = elapsed()
53+
} else if (allDependencies.length) {
54+
content = transformDependencies(content)
55+
mkdirSync(tmpdir, { recursive: true })
3856
}
3957

40-
const cwd = dependencies.length ? tmpdir : process.cwd()
58+
const cwd = allDependencies.length ? tmpdir : process.cwd()
4159
const elapsed = timeSpan()
42-
const result = await build({ content, cwd })
60+
const result = await build({ content, cwd, nodePaths })
4361
phases.build = elapsed()
4462
content = result.outputFiles[0].text
4563

src/compile/install-dependencies.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,6 @@ module.exports = async ({ dependencies, cwd, allow = {} }) => {
5656
validateDependencies(dependencies, allow.dependencies)
5757
return $(`${install} ${dependencies.join(' ')}`, { cwd, env: { ...process.env, CI: true } })
5858
}
59+
60+
module.exports.validateDependencies = validateDependencies
61+
module.exports.extractPackageName = extractPackageName

src/index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ export interface AllowOptions {
7373
export interface CreateOptions {
7474
/** Directory for installing code dependencies. Reused across invocations. */
7575
tmpdir?: string
76+
/** Additional directories for resolving dependencies. Dependencies found here with a matching version skip npm install. */
77+
nodePaths?: string[]
7678
}
7779

7880
/**

src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ const spawn = ({ args, env, timeout }) => {
4040
return $('node', ['-', args], spawnOpts)
4141
}
4242

43-
module.exports = ({ tmpdir } = {}) => {
43+
module.exports = ({ tmpdir, nodePaths } = {}) => {
4444
const isolatedFunction = (snippet, { timeout, memory, throwError = true, allow = {} } = {}) => {
4545
if (!['function', 'string'].includes(typeof snippet)) throw new TypeError('Expected a function')
4646
const { permissions = [] } = allow
47-
const compilePromise = compile(snippet, { tmpdir, allow })
47+
const compilePromise = compile(snippet, { tmpdir, allow, nodePaths })
4848

4949
return async (...args) => {
5050
let total

0 commit comments

Comments
 (0)