diff --git a/README.md b/README.md index b698874d..aba46eff 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ Type: `Function` Default: `null` You can provide a custom path resolver with this option. This function gets -`(id, basedir, importOptions)` arguments and should return a path, an array of +`(id, basedir, importOptions, astNode)` arguments and should return a path, an array of paths or a promise resolving to the path(s). If you do not return an absolute path, your path will be resolved to an absolute path using the default resolver. diff --git a/lib/parse-styles.js b/lib/parse-styles.js index d021dd4d..ec543d7d 100644 --- a/lib/parse-styles.js +++ b/lib/parse-styles.js @@ -50,8 +50,8 @@ async function parseStyles( else if ( stmt.node.params.toLowerCase() !== charset.node.params.toLowerCase() ) { - throw new Error( - `Incompatable @charset statements: + throw stmt.node.error( + `Incompatible @charset statements: ${stmt.node.params} specified in ${stmt.node.source.input.file} ${charset.node.params} specified in ${charset.node.source.input.file}` ) @@ -108,12 +108,14 @@ async function resolveImportId(result, stmt, options, state, postcss) { ? path.dirname(atRule.source.input.file) : options.root - const paths = [await options.resolve(stmt.uri, base, options)].flat() + const paths = [await options.resolve(stmt.uri, base, options, atRule)].flat() // Ensure that each path is absolute: const resolved = await Promise.all( paths.map(file => { - return !path.isAbsolute(file) ? resolveId(file, base, options) : file + return !path.isAbsolute(file) + ? resolveId(file, base, options, atRule) + : file }) ) diff --git a/lib/resolve-id.js b/lib/resolve-id.js index d6d16686..aca3002d 100644 --- a/lib/resolve-id.js +++ b/lib/resolve-id.js @@ -11,7 +11,7 @@ function resolveModule(id, opts) { }) } -module.exports = function resolveId(id, base, options) { +module.exports = function resolveId(id, base, options, node) { const paths = options.path const resolveOpts = { @@ -32,10 +32,10 @@ module.exports = function resolveId(id, base, options) { .catch(() => { if (paths.indexOf(base) === -1) paths.unshift(base) - throw new Error( + throw node.error( `Failed to find '${id}' in [ - ${paths.join(",\n ")} + ${paths.join(",\n ")} ]` ) }) diff --git a/test/import.js b/test/import.js index c13bd769..ea4a9c1f 100644 --- a/test/import.js +++ b/test/import.js @@ -63,7 +63,7 @@ test( "charset-import" ) -test("should error if incompatable @charset statements", t => { +test("should error if incompatible @charset statements", t => { t.plan(2) const file = "test/fixtures/charset-error.css" return postcss() @@ -73,7 +73,7 @@ test("should error if incompatable @charset statements", t => { t.truthy(err) t.regex( err.message, - /Incompatable @charset statements:.+specified in.+specified in.+/s + /Incompatible @charset statements:.+specified in.+specified in.+/s ) }) }) diff --git a/test/layer.js b/test/layer.js index 69d27afd..3414ff08 100644 --- a/test/layer.js +++ b/test/layer.js @@ -49,7 +49,9 @@ test("should error when value is not a function", t => { return postcss() .use(atImport({ nameLayer: "not a function" })) .process("", { from: undefined }) - .catch(error => t.is(error.message, "nameLayer option must be a function")) + .catch(error => + t.regex(error.message, /nameLayer option must be a function/) + ) }) test("should throw when using anonymous layers without the nameLayer plugin option", t => { diff --git a/test/plugins.js b/test/plugins.js index 20cee886..31df1ffb 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -35,7 +35,7 @@ test("should error when value is not an array", t => { return postcss() .use(atImport({ plugins: "foo" })) .process("", { from: undefined }) - .catch(error => t.is(error.message, "plugins option must be an array")) + .catch(error => t.regex(error.message, /plugins option must be an array/)) }) test("should remain silent when value is an empty array", t => {