@@ -6,7 +6,55 @@ const { createHash } = require("./utilities/hash")
66class TranslationError extends Error {
77 constructor ( message ) {
88 super ( message )
9- this . name = 'TranslationError'
9+ this . name = "TranslationError"
10+ Error . captureStackTrace ( this , this . constructor )
11+ }
12+ }
13+
14+ class FileError extends Error {
15+ constructor ( message ) {
16+ super ( message )
17+ this . name = "FileError"
18+ Error . captureStackTrace ( this , this . constructor )
19+ }
20+ }
21+
22+ class RawError extends Error {
23+ constructor ( message ) {
24+ super ( message )
25+ this . name = "RawError"
26+ Error . captureStackTrace ( this , this . constructor )
27+ }
28+ }
29+
30+ class CSSError extends Error {
31+ constructor ( message ) {
32+ super ( message )
33+ this . name = "CSSError"
34+ Error . captureStackTrace ( this , this . constructor )
35+ }
36+ }
37+
38+ class ImageError extends Error {
39+ constructor ( message ) {
40+ super ( message )
41+ this . name = "ImageError"
42+ Error . captureStackTrace ( this , this . constructor )
43+ }
44+ }
45+
46+ class SVGError extends Error {
47+ constructor ( message ) {
48+ super ( message )
49+ this . name = "SVGError"
50+ Error . captureStackTrace ( this , this . constructor )
51+ }
52+ }
53+
54+ class JSONError extends Error {
55+ constructor ( message ) {
56+ super ( message )
57+ this . name = "JSONError"
1058 Error . captureStackTrace ( this , this . constructor )
1159 }
1260}
@@ -45,7 +93,7 @@ function compile(path) {
4593 if (
4694 attributes . src ||
4795 [ "application/json" , "application/ld+json" ] . includes (
48- attributes . type
96+ attributes . type ,
4997 )
5098 ) {
5199 node . ignore = false
@@ -187,7 +235,7 @@ function validateSymlinks(path, base) {
187235 if ( ! part ) continue
188236 current = resolve ( current , part )
189237 if ( lstatSync ( current ) . isSymbolicLink ( ) ) {
190- throw new Error ( `FileError: symlinks are not allowed ("${ current } ")`)
238+ throw new FileError ( ` symlinks are not allowed ("${ current } ")`)
191239 }
192240 }
193241}
@@ -199,33 +247,31 @@ function validateFile(path, base) {
199247 const type = extension ( normalizedPath )
200248
201249 if ( ! type ) {
202- throw new Error ( `FileError: path "${ path } " has no extension`)
250+ throw new FileError ( ` path "${ path } " has no extension`)
203251 }
204252
205253 if ( ! ALLOWED_READ_EXTENSIONS . includes ( type ) ) {
206- throw new Error (
207- `FileError: unsupported file type "${ type } " for path "${ path } "`
208- )
254+ throw new FileError ( `unsupported file type "${ type } " for path "${ path } "` )
209255 }
210256
211257 const stats = lstatSync ( normalizedPath )
212258 if ( ! stats . isFile ( ) ) {
213- throw new Error ( `FileError: path "${ path } " is not a file`)
259+ throw new FileError ( ` path "${ path } " is not a file`)
214260 }
215261
216262 if ( stats . isSymbolicLink ( ) ) {
217- throw new Error ( `FileError: path "${ path } " is a symbolic link`)
263+ throw new FileError ( ` path "${ path } " is a symbolic link`)
218264 }
219265
220266 if ( normalizedPath === normalizedBase ) {
221- throw new Error (
222- `FileError: path "${ path } " is the same as the current working directory "${ base } "`
267+ throw new FileError (
268+ `path "${ path } " is the same as the current working directory "${ base } "` ,
223269 )
224270 }
225271
226272 if ( ! normalizedPath . startsWith ( normalizedBase + "/" ) ) {
227- throw new Error (
228- `FileError: real path "${ realPath } " is not within the current working directory "${ realBase } "`
273+ throw new FileError (
274+ `real path "${ realPath } " is not within the current working directory "${ realBase } "` ,
229275 )
230276 }
231277}
@@ -243,9 +289,7 @@ function readFile(path, encoding) {
243289
244290 return readFileSync ( path , encoding )
245291 } catch ( exception ) {
246- throw new Error (
247- `FileError: cannot read file "${ path } ": ${ exception . message } `
248- )
292+ throw new FileError ( `cannot read file "${ path } ": ${ exception . message } ` )
249293 }
250294}
251295
@@ -338,8 +382,8 @@ const attributes = (options) => {
338382 const left = result . left || "0"
339383 styles . push (
340384 `${ decamelize ( param ) } :${ escapeHTML (
341- `${ top } ${ right } ${ bottom } ${ left } `
342- ) } `
385+ `${ top } ${ right } ${ bottom } ${ left } ` ,
386+ ) } `,
343387 )
344388 } else if ( typeof result === "string" || typeof result === "number" ) {
345389 styles . push ( `${ decamelize ( param ) } :${ escapeHTML ( result ) } ` )
@@ -488,9 +532,7 @@ const sanitizeHTML = (content) => {
488532raw . load = function ( path , options = { } ) {
489533 const type = extension ( path )
490534 if ( ! ALLOWED_RAW_EXTENSIONS . includes ( type ) ) {
491- throw new Error (
492- `RawError: unsupported raw type "${ type } " for path "${ path } "`
493- )
535+ throw new RawError ( `unsupported raw type "${ type } " for path "${ path } "` )
494536 }
495537
496538 let content = readFile ( path , "utf8" )
@@ -647,7 +689,7 @@ css.load = function (path) {
647689 const content = readFile ( file , "utf8" )
648690 const { valid, message } = isCSSValid ( content )
649691 if ( ! valid ) {
650- throw new Error ( `CSSError: invalid CSS for path "${ file } ": ${ message } `)
692+ throw new CSSError ( ` invalid CSS for path "${ file } ": ${ message } `)
651693 }
652694 return css `
653695 ${ content }
@@ -879,9 +921,7 @@ function base64({ content, path }) {
879921nodes . Img . load = function ( path ) {
880922 const type = extension ( path )
881923 if ( ! ALLOWED_IMAGE_EXTENSIONS . includes ( type ) ) {
882- throw new Error (
883- `ImageError: unsupported image type "${ type } " for path "${ path } "`
884- )
924+ throw new ImageError ( `unsupported image type "${ type } " for path "${ path } "` )
885925 }
886926 const content = readFile ( path , "base64" )
887927 return ( options ) => {
@@ -934,9 +974,7 @@ const sanitizeSVG = (content) => {
934974nodes . Svg . load = function ( path , options = { } ) {
935975 const type = extension ( path )
936976 if ( type !== "svg" ) {
937- throw new Error (
938- `SVGError: unsupported SVG type "${ type } " for path "${ path } "`
939- )
977+ throw new SVGError ( `unsupported SVG type "${ type } " for path "${ path } "` )
940978 }
941979 let content = readFile ( path , "utf8" )
942980 if ( options . sanitize !== false ) {
@@ -976,26 +1014,28 @@ const json = {
9761014 try {
9771015 return JSON . parse ( content )
9781016 } catch ( exception ) {
979- throw new Error (
980- `JSONError: cannot parse file "${ file } ": ${ exception . message } `
981- )
1017+ throw new JSONError ( `cannot parse file "${ file } ": ${ exception . message } ` )
9821018 }
9831019 } ,
9841020}
9851021
9861022function i18n ( translations ) {
9871023 return function translate ( language , key ) {
9881024 if ( key === undefined ) {
989- throw new TranslationError ( ' key is undefined' )
1025+ throw new TranslationError ( " key is undefined" )
9901026 }
9911027 if ( language === undefined ) {
992- throw new TranslationError ( ' language is undefined' )
1028+ throw new TranslationError ( " language is undefined" )
9931029 }
9941030 if ( translations [ key ] === undefined ) {
995- throw new TranslationError ( `translation [${ key } ][${ language } ] is undefined` )
1031+ throw new TranslationError (
1032+ `translation [${ key } ][${ language } ] is undefined` ,
1033+ )
9961034 }
9971035 if ( translations [ key ] [ language ] === undefined ) {
998- throw new TranslationError ( `translation [${ key } ][${ language } ] is undefined` )
1036+ throw new TranslationError (
1037+ `translation [${ key } ][${ language } ] is undefined` ,
1038+ )
9991039 }
10001040 return translations [ key ] [ language ]
10011041 }
@@ -1022,7 +1062,7 @@ i18n.load = function (path, options = {}) {
10221062 }
10231063 if ( ! data [ key ] || ! data [ key ] [ language ] ) {
10241064 throw new TranslationError (
1025- `translation [${ key } ][${ language } ] is undefined`
1065+ `translation [${ key } ][${ language } ] is undefined` ,
10261066 )
10271067 }
10281068 return data [ key ] [ language ]
@@ -1037,19 +1077,19 @@ function component(fn, { styles, i18n, scripts } = {}) {
10371077 if ( i18n ) {
10381078 if ( ! a || ! a . language ) {
10391079 throw new TranslationError (
1040- `language is undefined for component:\n${ fn . toString ( ) } `
1080+ `language is undefined for component:\n${ fn . toString ( ) } ` ,
10411081 )
10421082 }
10431083 const { language } = a
10441084 function translate ( key ) {
10451085 if ( ! key ) {
10461086 throw new TranslationError (
1047- `key is undefined for component:\n${ fn . toString ( ) } `
1087+ `key is undefined for component:\n${ fn . toString ( ) } ` ,
10481088 )
10491089 }
10501090 if ( ! i18n [ key ] || ! i18n [ key ] [ language ] ) {
10511091 throw new TranslationError (
1052- `translation [${ key } ][${ language } ] is undefined for component:\n${ fn . toString ( ) } `
1092+ `translation [${ key } ][${ language } ] is undefined for component:\n${ fn . toString ( ) } ` ,
10531093 )
10541094 }
10551095 const translation = i18n [ key ] [ language ]
@@ -1090,5 +1130,11 @@ module.exports = {
10901130 tag,
10911131 i18n,
10921132 TranslationError,
1133+ FileError,
1134+ RawError,
1135+ CSSError,
1136+ ImageError,
1137+ SVGError,
1138+ JSONError,
10931139 ...nodes ,
10941140}
0 commit comments