Skip to content

Commit 87e954a

Browse files
committed
[Fix] sync/async: when package.json main is not a string, throw an error
Fixes #178.
1 parent 8fb6d96 commit 87e954a

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

lib/async.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ module.exports = function resolve(x, options, callback) {
185185
}
186186

187187
if (pkg.main) {
188+
if (typeof pkg.main !== 'string') {
189+
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
190+
mainError.code = 'INVALID_PACKAGE_MAIN';
191+
return cb(mainError);
192+
}
188193
if (pkg.main === '.' || pkg.main === './') {
189194
pkg.main = 'index';
190195
}

lib/sync.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,21 +118,28 @@ module.exports = function (x, options) {
118118
try {
119119
var body = readFileSync(pkgfile, 'UTF8');
120120
var pkg = JSON.parse(body);
121+
} catch (e) {}
121122

122-
if (opts.packageFilter) {
123-
pkg = opts.packageFilter(pkg, x);
124-
}
123+
if (opts.packageFilter) {
124+
pkg = opts.packageFilter(pkg, x);
125+
}
125126

126-
if (pkg.main) {
127-
if (pkg.main === '.' || pkg.main === './') {
128-
pkg.main = 'index';
129-
}
127+
if (pkg.main) {
128+
if (typeof pkg.main !== 'string') {
129+
var mainError = new TypeError('package “' + pkg.name + '” `main` must be a string');
130+
mainError.code = 'INVALID_PACKAGE_MAIN';
131+
throw mainError;
132+
}
133+
if (pkg.main === '.' || pkg.main === './') {
134+
pkg.main = 'index';
135+
}
136+
try {
130137
var m = loadAsFileSync(path.resolve(x, pkg.main));
131138
if (m) return m;
132139
var n = loadAsDirectorySync(path.resolve(x, pkg.main));
133140
if (n) return n;
134-
}
135-
} catch (e) {}
141+
} catch (e) {}
142+
}
136143
}
137144

138145
return loadAsFileSync(path.join(x, '/index'));

test/resolver.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,19 @@ test('not a directory', function (t) {
365365
});
366366
});
367367

368+
test('non-string "main" field in package.json', function (t) {
369+
t.plan(5);
370+
371+
var dir = path.join(__dirname, 'resolver');
372+
resolve('./invalid_main', { basedir: dir }, function (err, res, pkg) {
373+
t.ok(err, 'errors on non-string main');
374+
t.equal(err.message, 'package “invalid main” `main` must be a string');
375+
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
376+
t.equal(res, undefined, 'res is undefined');
377+
t.equal(pkg, undefined, 'pkg is undefined');
378+
});
379+
});
380+
368381
test('browser field in package.json', function (t) {
369382
t.plan(3);
370383

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "invalid main",
3+
"main": [
4+
"why is this a thing",
5+
"srsly omg wtf"
6+
]
7+
}

test/resolver_sync.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,20 @@ test('not a directory', function (t) {
283283
t.end();
284284
});
285285

286+
test('non-string "main" field in package.json', function (t) {
287+
var dir = path.join(__dirname, 'resolver');
288+
try {
289+
var result = resolve.sync('./invalid_main', { basedir: dir });
290+
t.equal(result, undefined, 'result should not exist');
291+
t.fail('should not get here');
292+
} catch (err) {
293+
t.ok(err, 'errors on non-string main');
294+
t.equal(err.message, 'package “invalid main” `main` must be a string');
295+
t.equal(err.code, 'INVALID_PACKAGE_MAIN');
296+
}
297+
t.end();
298+
});
299+
286300
test('browser field in package.json', function (t) {
287301
var dir = path.join(__dirname, 'resolver');
288302
var res = resolve.sync('./browser_field', {

0 commit comments

Comments
 (0)