1- let  path  =  require ( "node:path" ) ; 
2- let  sharp  =  require ( "sharp" ) ; 
3- let  svgo  =  require ( "svgo" ) ; 
4- let  {  readFile }  =  require ( "node:fs/promises" ) ; 
5- let  {  buildProcessPipeline }  =  require ( "faucet-pipeline-static/lib/util.js" ) ; 
6- let  {  abort }  =  require ( "faucet-pipeline-core/lib/util/index.js" ) ; 
1+ import  path  from  "node:path" ; 
2+ import  sharp  from  "sharp" ; 
3+ import  svgo  from  "svgo" ; 
4+ import  {  readFile  }  from  "node:fs/promises" ; 
5+ import  {  buildProcessPipeline  }  from  "faucet-pipeline-static/lib/util.js" ; 
6+ import  {  abort ,  repr  }  from  "faucet-pipeline-core/lib/util/index.js" ; 
7+ 
8+ export  const  key  =  "images" ; 
9+ export  const  bucket  =  "static" ; 
10+ 
11+ export  function  plugin ( config ,  assetManager )  { 
12+ 	let  pipeline  =  config . map ( optimizerConfig  =>  { 
13+ 		let  processFile  =  buildProcessFile ( optimizerConfig ) ; 
14+ 		let  {  source,  target }  =  optimizerConfig ; 
15+ 		let  filter  =  optimizerConfig . filter  || 
16+ 			withFileExtension ( "avif" ,  "jpg" ,  "jpeg" ,  "png" ,  "webp" ,  "svg" ) ; 
17+ 		return  buildProcessPipeline ( source ,  target ,  processFile ,  assetManager ,  filter ) ; 
18+ 	} ) ; 
19+ 
20+ 	return  filepaths  =>  Promise . all ( pipeline . map ( optimize  =>  optimize ( filepaths ) ) ) ; 
21+ } 
722
823// we can optimize the settings here, but some would require libvips 
924// to be compiled with additional stuff 
@@ -51,30 +66,8 @@ let settings = {
5166	avif : { } 
5267} ; 
5368
54- module . exports  =  { 
55- 	key : "images" , 
56- 	bucket : "static" , 
57- 	plugin : faucetImages 
58- } ; 
59- 
60- /** @type  FaucetPlugin<Config> */ 
61- function  faucetImages ( config ,  assetManager )  { 
62- 	let  pipeline  =  config . map ( optimizerConfig  =>  { 
63- 		let  processFile  =  buildProcessFile ( optimizerConfig ) ; 
64- 		let  {  source,  target }  =  optimizerConfig ; 
65- 		let  filter  =  optimizerConfig . filter  || 
66- 			withFileExtension ( "avif" ,  "jpg" ,  "jpeg" ,  "png" ,  "webp" ,  "svg" ) ; 
67- 		return  buildProcessPipeline ( source ,  target ,  processFile ,  assetManager ,  filter ) ; 
68- 	} ) ; 
69- 
70- 	return  filepaths  =>  Promise . all ( pipeline . map ( optimize  =>  optimize ( filepaths ) ) ) ; 
71- } 
72- 
7369/** 
7470 * Returns a function that processes a single file 
75-  * 
76-  * @param  {Config } config 
77-  * @returns  {ProcessFile } 
7871 */ 
7972function  buildProcessFile ( config )  { 
8073	return  async  function ( filename , 
@@ -88,7 +81,6 @@ function buildProcessFile(config) {
8881			await  optimizeSVG ( sourcePath )  :
8982			await  optimizeBitmap ( sourcePath ,  format ,  config ) ; 
9083
91- 		/** @type  WriteFileOpts */ 
9284		let  writeOptions  =  {  targetDir } ; 
9385		if ( config . fingerprint  !==  undefined )  { 
9486			writeOptions . fingerprint  =  config . fingerprint ; 
@@ -98,6 +90,8 @@ function buildProcessFile(config) {
9890} 
9991
10092/** 
93+  * Optimize a single SVG 
94+  * 
10195 * @param  {string } sourcePath 
10296 * @returns  {Promise<string> } 
10397 */ 
@@ -108,15 +102,16 @@ async function optimizeSVG(sourcePath) {
108102		let  output  =  await  svgo . optimize ( input ,  settings . svg ) ; 
109103		return  output . data ; 
110104	}  catch ( error )  { 
111- 		abort ( `Only SVG can be converted to SVG: ${ sourcePath }  ` ) ; 
112- 		return  "" ;  // XXX: this is for typescript :joy: 
105+ 		abort ( `Only SVG can be converted to SVG: ${ repr ( sourcePath ) }  ` ) ; 
113106	} 
114107} 
115108
116109/** 
110+  * Optimize a single bitmap image 
111+  * 
117112 * @param  {string } sourcePath 
118113 * @param  {string } format 
119-  * @param  {ImageOptions } options 
114+  * @param  {Object } options 
120115 * @returns  {Promise<Buffer> } 
121116 */ 
122117async  function  optimizeBitmap ( sourcePath ,  format , 
@@ -138,8 +133,6 @@ async function optimizeBitmap(sourcePath, format,
138133
139134	if ( width  ||  height )  { 
140135		let  fit  =  crop  ? "cover"  : "inside" ; 
141- 		// XXX: Fixme 
142- 		// @ts -ignore 
143136		image . resize ( {  width,  height,  fit : sharp . fit [ fit ]  } ) ; 
144137	} 
145138
@@ -158,15 +151,15 @@ async function optimizeBitmap(sourcePath, format,
158151		image . avif ( {  ...settings . avif ,  quality } ) ; 
159152		break ; 
160153	default :
161- 		abort ( `unsupported format ${ format }  . We support: AVIF, JPG, PNG, WebP, SVG` ) ; 
154+ 		abort ( `unsupported format ${ repr ( format ) }  . We support: AVIF, JPG, PNG, WebP, SVG` ) ; 
162155	} 
163156
164157	return  image . toBuffer ( ) ; 
165158} 
166159
167160/** 
168161 * @param  {string } filepath 
169-  * @param  {TargetPathOpts } opts  
162+  * @param  {Object } options  
170163 * @returns  {string } 
171164 */ 
172165function  determineTargetPath ( filepath ,  {  format,  suffix =  ""  } )  { 
@@ -186,26 +179,11 @@ function withFileExtension(...extensions) {
186179} 
187180
188181/** 
189-  * extname follows this annoying idea that  the dot belongs to the extension  
182+  * File extension of a filename without  the dot 
190183 * 
191184 * @param  {string } filename 
192185 * @returns  {string } 
193186 */ 
194187function  extname ( filename )  { 
195188	return  path . extname ( filename ) . slice ( 1 ) . toLowerCase ( ) ; 
196189} 
197- 
198- /** @import  { 
199- 	*   FaucetPlugin, 
200- 	*   FaucetPluginOptions, 
201- 	*   WriteFileOpts, 
202- 	*   Filter, 
203- 	*   ProcessFile 
204- 	* } from "faucet-pipeline-static/lib/types.ts" 
205- 	**/ 
206- /** @import  { 
207- 	*   Config, 
208- 	*   ImageOptions, 
209- 	*   TargetPathOpts 
210- 	* } from "./types.ts" 
211- 	**/ 
0 commit comments