"use strict" ;
const Promise = require ( "bluebird" ) ;
const bl = require ( "bl" ) ;
const through2 = require ( "through2" ) ;
const path = require ( "path" ) ;
const createFilePreprocessor = require ( "./postcss/preprocess" ) ;
const loaderShimPath = require ( "./loader-shim-path" ) ;
module . exports = function ( state ) {
const isCss = require ( "./is-css" ) ( state ) ;
return function createTransform ( file , options ) {
// TODO: Reuse instance?
let preprocessFile = createFilePreprocessor ( options ) ;
if ( isCss ( { file : file } ) ) {
let buffer = new bl . BufferList ( ) ;
function chunkHandler ( chunk , encoding , callback ) {
// NOTE: We check the `chunk` here, not the `encoding`, because in at least one instance a Buffer was passed in claiming to be a "utf8" string according to the `encoding` argument
if ( Buffer . isBuffer ( chunk ) ) {
buffer . append ( chunk ) ;
callback ( ) ;
} else {
throw new Error ( ` Expected Buffer, got string instead (encoding = ${ encoding } ) ` ) ;
}
}
function endHandler ( callback ) {
return Promise . try ( ( ) => {
return preprocessFile ( { file : file , source : buffer . toString ( ) } ) ;
} ) . then ( ( result ) => {
let imports = result . messages
. filter ( ( message ) => {
return (
message . pluginName === "postcss-icss-find-imports"
&& message . type === "import"
) ;
} )
. map ( ( message ) => message . url ) ;
imports . forEach ( ( importUrl ) => {
this . emit ( "dep" , importUrl ) ;
} ) ;
// This ensures that whenever *any* CSS file is processed, the global loader file gets included as well (which is the file that eventually inserts the concatenated CSS)
let relativeLoaderPath = path . relative ( path . dirname ( file ) , loaderShimPath ) ;
this . emit ( "dep" , relativeLoaderPath ) ;
this . push ( result . css ) ;
callback ( ) ;
} ) . catch ( ( error ) => {
callback ( error ) ;
} ) ;
}
return through2 . obj ( chunkHandler , endHandler ) ;
} else {
return through2 . obj ( ) ;
}
} ;
} ;