@@ -9,37 +9,46 @@ const RE_BLANK = /^[ \t]*$/;
9
9
* line and it must end on a line of its own, with the closing delimiter on a
10
10
* next line.
11
11
*
12
- * @param {Array<string> } strings
13
- * @param {...any } values
14
- * @returns string
12
+ * @param strings
13
+ * @param values
15
14
*/
16
- export default function ftl ( strings , ...values ) {
15
+ export default function ftl (
16
+ strings : TemplateStringsArray ,
17
+ ...values : Array < unknown >
18
+ ) : string {
17
19
let code = strings . reduce ( ( acc , cur ) => acc + values . shift ( ) + cur ) ;
18
20
let lines = code . split ( "\n" ) ;
19
- let [ first , commonIndent ] = [ lines . shift ( ) , lines . pop ( ) ] ;
20
21
21
- if ( ! RE_BLANK . test ( first ) ) {
22
+ let first = lines . shift ( ) ;
23
+ if ( first === undefined || ! RE_BLANK . test ( first ) ) {
22
24
throw new RangeError ( "Content must start on a new line." ) ;
23
25
}
24
- if ( ! RE_BLANK . test ( commonIndent ) ) {
26
+
27
+ let commonIndent = lines . pop ( ) ;
28
+ if ( commonIndent === undefined || ! RE_BLANK . test ( commonIndent ) ) {
25
29
throw new RangeError ( "Closing delimiter must appear on a new line." ) ;
26
30
}
27
31
28
- function dedent ( line , idx ) {
32
+ let dedented = [ ] ;
33
+ for ( let i = 0 ; i < lines . length ; i ++ ) {
34
+ let line = lines [ i ] ;
29
35
let lineIndent = line . slice ( 0 , commonIndent . length ) ;
30
36
if ( lineIndent . length === 0 ) {
31
37
// Empty blank lines are preserved even if technically they are not
32
38
// indented at all. This also short-circuits the dedentation logic when
33
39
// commonIndent.length is 0, i.e. when all indents should be kept.
34
- return line ;
40
+ dedented . push ( line ) ;
41
+ continue ;
35
42
}
43
+
36
44
if ( lineIndent !== commonIndent ) {
37
45
// The indentation of the line must match commonIndent exacty.
38
- throw new RangeError ( `Insufficient indentation in line ${ idx + 1 } .` ) ;
46
+ throw new RangeError ( `Insufficient indentation in line ${ i + 1 } .` ) ;
39
47
}
48
+
40
49
// Strip commonIndent.
41
- return line . slice ( commonIndent . length ) ;
50
+ dedented . push ( line . slice ( commonIndent . length ) ) ;
42
51
}
43
52
44
- return lines . map ( dedent ) . join ( "\n" ) ;
53
+ return dedented . join ( "\n" ) ;
45
54
}
0 commit comments