diff --git a/src/file.js b/src/file.js index 9f76fb3b..07a8aee8 100644 --- a/src/file.js +++ b/src/file.js @@ -62,7 +62,9 @@ export function normalizePath(str) { * @returns {boolean} True if the path is remote */ export function isRemote(href) { - return !Buffer.isBuffer(href) && /(^\/\/)|(:\/\/)/.test(href) && !href.startsWith('file:'); + return ( + typeof href === 'string' && !Buffer.isBuffer(href) && /(^\/\/)|(:\/\/)/.test(href) && !href.startsWith('file:') + ); } /** @@ -88,8 +90,8 @@ export function urlParse(str = '') { * @returns {string} file uri */ function getFileUri(file) { - if (!isAbsolute) { - throw new Error('Path must be absolute to compute file uri'); + if (!isAbsolute(file)) { + throw new Error('Path must be absolute to compute file uri. Received: ' + file); } const fileUrl = process.platform === 'win32' ? new URL(`file:///${file}`) : new URL(`file://${file}`); @@ -117,8 +119,12 @@ export function urlResolve(from = '', to = '') { return path.join(from.replace(/[^/]+$/, ''), to); } -function isAbsolute(href) { - return !Buffer.isBuffer(href) && path.isAbsolute(href); +function isFilePath(href) { + return typeof href === 'string' && !Buffer.isBuffer(href) && !isRemote(href); +} + +export function isAbsolute(href) { + return isFilePath(href) && path.isAbsolute(href); } /** @@ -127,7 +133,7 @@ function isAbsolute(href) { * @returns {boolean} True if the path is relative */ function isRelative(href) { - return !Buffer.isBuffer(href) && !isRemote(href) && !isAbsolute(href); + return isFilePath(href) && !isAbsolute(href); } /** @@ -518,8 +524,6 @@ export async function getDocumentPath(file, options = {}) { return normalizePath(`/${path.relative(base, file.path || base)}`); } - console.log('getDocumentPath') - // Check local and assume base path based on relative stylesheets if (file.stylesheets) { const relativeRefs = file.stylesheets.filter((href) => isRelative(href)); @@ -720,7 +724,7 @@ export async function getAssetPaths(document, file, options = {}, strict = true) // Filter non-existent paths const filtered = await filterAsync(paths, (f) => { - if (!f || (!isRemote(f) && !f?.includes(process.cwd()))) { + if (!f || (isAbsolute(f) && !f?.includes(process.cwd()))) { return false; } diff --git a/test/cli.test.js b/test/cli.test.js index ca7516d0..9a28f210 100644 --- a/test/cli.test.js +++ b/test/cli.test.js @@ -38,18 +38,15 @@ const getArgs = async (params = []) => { await import('../cli.js'); process.argv = origArgv; const {generate} = await import('../index.js'); - // console.log('GENERATE:', generate.mock); const [args] = generate.mock.calls; const [opts] = args || [{}]; expect(generate).toHaveBeenCalledTimes(1); return opts || {}; - // return {}; }; const pipe = async (filename, args = []) => { const cat = process.platform === 'win32' ? 'type' : 'cat'; const cmd = `${cat} ${filename} | node ${criticalBin} ${args.join(' ')}`; - console.log(cmd); return pExec(cmd, {shell: true}); }; @@ -105,7 +102,7 @@ describe('CLI', () => { expect(nn(stdout)).toBe(expected); }); - test.only('Pipe html file inside a folder to critical', async () => { + test('Pipe html file inside a folder to critical', async () => { const {stdout, stderr} = await pipe(path.normalize('fixtures/folder/generate-default.html'), [ '--base', 'fixtures', diff --git a/test/file.test.js b/test/file.test.js index 99950ee4..a8a659c8 100644 --- a/test/file.test.js +++ b/test/file.test.js @@ -16,6 +16,7 @@ import {FileNotFoundError} from '../src/errors.js'; import { BASE_WARNING, isRemote, + isAbsolute, checkCssOption, fileExists, joinPath, @@ -88,6 +89,18 @@ test('Remote file detection', () => { remote.forEach((p) => expect(isRemote(p)).toBe(true)); }); +test('Absolute file detection', () => { + const invalid = ['', false, {}]; + const absolute = ['/usr/tmp/bar']; + const relative = ['../test/foo.html', './usr/tmp/bar']; + const remote = ['https://test.io/', '//test.io/styles/main.css']; + + invalid.forEach((p) => expect(isAbsolute(p)).toBe(false)); + relative.forEach((p) => expect(isAbsolute(p)).toBe(false)); + remote.forEach((p) => expect(isAbsolute(p)).toBe(false)); + absolute.forEach((p) => expect(isAbsolute(p)).toBe(true)); +}); + test('Error for file not found', () => { expect(vinylize({filenpath: 'non-existant-file.html'})).rejects.toThrow(FileNotFoundError); });