'use strict' const { join } = require('path') const { test } = require('tap') const { when } = require('nonsynchronous') const { chmodSync } = require('fs') const isFileEsm = require('..') const { ERR_PATH_MUST_BE_STRING, ERR_PATH_MUST_BE_ABSOLUTE, ERR_PATH_MUST_EXIST, ERR_PATH_MUST_HAVE_VALID_EXT } = isFileEsm.constants const ERR_BAD_TYPE = 'package.json type "bad" not recognized' const ERR_PERMISSION_DENIED = /EACCES: permission denied/ const fixtures = join(__dirname, 'fixtures') test('path must be string (promise)', async ({ rejects }) => { await rejects(() => isFileEsm(), Error(ERR_PATH_MUST_BE_STRING)) await rejects(() => isFileEsm({}), Error(ERR_PATH_MUST_BE_STRING)) }) test('path must be absolute (promise)', async ({ rejects }) => { await rejects(() => isFileEsm('../foo.js'), Error(ERR_PATH_MUST_BE_ABSOLUTE)) await rejects(() => isFileEsm('./bar/foo.mjs'), Error(ERR_PATH_MUST_BE_ABSOLUTE)) }) test('path must have ext (promise)', async ({ rejects }) => { await rejects(() => isFileEsm('/bar/foo'), Error(ERR_PATH_MUST_HAVE_VALID_EXT)) }) test('path must have valid ext (promise)', async ({ rejects }) => { await rejects(() => isFileEsm('/bar/foo.ext'), Error(ERR_PATH_MUST_HAVE_VALID_EXT)) }) test('path must exist (promise)', async ({ rejects }) => { await rejects(() => isFileEsm(join(fixtures, 'bar', 'foo.js')), Error(ERR_PATH_MUST_EXIST)) }) test('type-commonjs-cjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'c') }) test('type-commonjs-js promise', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'j') }) test('type-commonjs-mjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'm') }) test('type-module-cjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'c') }) test('type-module-js promise', async ({ is }) => { const inputPath = join(fixtures, 'type-module-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'j') }) test('type-module-mjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'm') }) test('type-undefined-cjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'c') }) test('type-undefined-js promise', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'j') }) test('type-undefined-mjs promise', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = await isFileEsm(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'm') }) test('type-bad-cjs promise', async ({ is, rejects }) => { const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json') let error = null await rejects(async () => { try { await isFileEsm(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'c') }) test('type-bad-js promise', async ({ is, rejects }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') let error = null await rejects(async () => { try { await isFileEsm(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'j') }) test('type-bad-mjs promise', async ({ is, rejects }) => { const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json') let error = null await rejects(async () => { try { await isFileEsm(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'm') }) test('package.json read error propagation (promise)', async ({ rejects, tearDown }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') tearDown(() => chmodSync(expectedPkgPath, 0o644)) chmodSync(expectedPkgPath, 0o000) await rejects(() => isFileEsm(inputPath), ERR_PERMISSION_DENIED) }) test('type-commonjs-cjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'c') }) test('type-commonjs-js sync', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'j') }) test('type-commonjs-mjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'm') }) test('type-module-cjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'c') }) test('type-module-js sync', async ({ is }) => { const inputPath = join(fixtures, 'type-module-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'j') }) test('type-module-mjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'm') }) test('type-undefined-cjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'c') }) test('type-undefined-js sync', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'j') }) test('type-undefined-mjs sync', async ({ is }) => { const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json') const { esm, path, type, extType, pkgPath } = isFileEsm.sync(inputPath) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'm') }) test('path must be string (sync)', async ({ throws }) => { throws(() => isFileEsm.sync(), Error(ERR_PATH_MUST_BE_STRING)) throws(() => isFileEsm.sync({}), Error(ERR_PATH_MUST_BE_STRING)) }) test('path must be absolute (sync)', async ({ throws }) => { throws(() => isFileEsm.sync('../foo.js'), Error(ERR_PATH_MUST_BE_ABSOLUTE)) throws(() => isFileEsm.sync('./bar/foo.mjs'), Error(ERR_PATH_MUST_BE_ABSOLUTE)) }) test('path must have ext (sync)', async ({ throws }) => { throws(() => isFileEsm.sync('/bar/foo'), Error(ERR_PATH_MUST_HAVE_VALID_EXT)) }) test('path must have valid ext (sync)', async ({ throws }) => { throws(() => isFileEsm.sync('/bar/foo.ext'), Error(ERR_PATH_MUST_HAVE_VALID_EXT)) }) test('path must exist (promise)', async ({ throws }) => { throws(() => isFileEsm.sync(join(fixtures, 'bar', 'foo.js')), Error(ERR_PATH_MUST_EXIST)) }) test('type-bad-cjs sync', async ({ is, throws }) => { const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json') let error = null throws(() => { try { isFileEsm.sync(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'c') }) test('type-bad-js sync', async ({ is, throws }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') let error = null throws(() => { try { isFileEsm.sync(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'j') }) test('type-bad-mjs sync', async ({ is, throws }) => { const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json') let error = null throws(() => { try { isFileEsm.sync(inputPath) } catch (err) { error = err throw err } }, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = error.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'm') }) test('package.json read error propagation (sync)', async ({ throws, tearDown }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') tearDown(() => chmodSync(expectedPkgPath, 0o644)) chmodSync(expectedPkgPath, 0o000) throws(() => isFileEsm.sync(inputPath), ERR_PERMISSION_DENIED) }) test('type-commonjs-cjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-commonjs-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-commonjs-cjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'c') until() }) await until.done() }) test('type-commonjs-js callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-commonjs-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-commonjs-js', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'j') until() }) await until.done() }) test('type-commonjs-mjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-commonjs-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-commonjs-mjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'commonjs') is(extType, 'm') until() }) await until.done() }) test('type-module-cjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-module-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-module-cjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'c') until() }) await until.done() }) test('type-module-js callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-module-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-module-js', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'j') until() }) await until.done() }) test('type-module-mjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-module-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-module-mjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'module') is(extType, 'm') until() }) await until.done() }) test('type-undefined-cjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-undefined-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-undefined-cjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'c') until() }) await until.done() }) test('type-undefined-js callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-undefined-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-undefined-js', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, false) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'j') until() }) await until.done() }) test('type-undefined-mjs callback', async ({ is, error }) => { const inputPath = join(fixtures, 'type-undefined-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-undefined-mjs', 'package.json') const until = when() isFileEsm(inputPath, (err, { esm, path, type, extType, pkgPath }) => { error(err) is(esm, true) is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, undefined) is(extType, 'm') until() }) await until.done() }) test('path must be string (callback)', async ({ match }) => { const until1 = when() isFileEsm(undefined, (err) => { match(err, Error(ERR_PATH_MUST_BE_STRING)) until1() }) const until2 = when() isFileEsm({}, (err) => { match(err, Error(ERR_PATH_MUST_BE_STRING)) until2() }) await Promise.all([until1.done(), until2.done()]) }) test('path must be absolute (callback)', async ({ match }) => { const until1 = when() isFileEsm('../foo.js', (err) => { match(err, Error(ERR_PATH_MUST_BE_ABSOLUTE)) until1() }) const until2 = when() isFileEsm('./bar/foo.mjs', (err) => { match(err, Error(ERR_PATH_MUST_BE_ABSOLUTE)) until2() }) await Promise.all([until1.done(), until2.done()]) }) test('path must have ext (callback)', async ({ match }) => { const until = when() isFileEsm('/bar/foo', (err) => { match(err, Error(ERR_PATH_MUST_HAVE_VALID_EXT)) until() }) await until.done() }) test('path must have valid ext (callback)', async ({ match }) => { const until = when() isFileEsm('/bar/foo.ext', (err) => { match(err, Error(ERR_PATH_MUST_HAVE_VALID_EXT)) until() }) await until.done() }) test('path must exist (callback)', async ({ match }) => { const until = when() isFileEsm(join(fixtures, 'bar', 'foo.js'), (err) => { match(err, Error(ERR_PATH_MUST_EXIST)) until() }) await until.done() }) test('type-bad-cjs callback', async ({ is }) => { const inputPath = join(fixtures, 'type-bad-cjs', 'file.cjs') const expectedPkgPath = join(fixtures, 'type-bad-cjs', 'package.json') const until = when() isFileEsm(inputPath, (err) => { is(err.message, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = err.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'c') until() }) await until.done() }) test('type-bad-js callback', async ({ is }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') const until = when() isFileEsm(inputPath, (err) => { is(err.message, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = err.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'j') until() }) await until.done() }) test('type-bad-mjs callback', async ({ is }) => { const inputPath = join(fixtures, 'type-bad-mjs', 'file.mjs') const expectedPkgPath = join(fixtures, 'type-bad-mjs', 'package.json') const until = when() isFileEsm(inputPath, (err) => { is(err.message, ERR_BAD_TYPE) const { path, type, extType, pkgPath } = err.meta is(path, inputPath) is(expectedPkgPath, pkgPath) is(type, 'bad') is(extType, 'm') until() }) await until.done() }) test('package.json read error propagation (callback)', async ({ match, tearDown }) => { const inputPath = join(fixtures, 'type-bad-js', 'file.js') const expectedPkgPath = join(fixtures, 'type-bad-js', 'package.json') tearDown(() => chmodSync(expectedPkgPath, 0o644)) chmodSync(expectedPkgPath, 0o000) const until = when() isFileEsm(inputPath, (err) => { match(err, ERR_PERMISSION_DENIED) until() }) await until.done() })