6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
+ import MagicString from 'magic-string' ;
9
10
import { ContentHasMutatedException } from '../exception/exception' ;
10
- import { UpdateBufferBase } from '../utility/update-buffer' ;
11
+ import { IndexOutOfBoundException } from '../utility/update-buffer' ;
11
12
import { FileEntry , UpdateRecorder } from './interface' ;
12
13
13
14
export class UpdateRecorderBase implements UpdateRecorder {
14
15
protected _path : string ;
15
- protected _original : Buffer ;
16
- protected _content : UpdateBufferBase ;
16
+ protected content : MagicString ;
17
+
18
+ constructor (
19
+ private readonly data : Uint8Array ,
20
+ path : string ,
21
+ encoding = 'utf-8' ,
22
+ private readonly bom = false ,
23
+ ) {
24
+ let text ;
25
+ try {
26
+ text = new TextDecoder ( encoding , { fatal : true , ignoreBOM : false } ) . decode ( data ) ;
27
+ } catch ( e ) {
28
+ if ( e instanceof TypeError ) {
29
+ throw new Error ( `Failed to decode "${ path } " as ${ encoding } text.` ) ;
30
+ }
31
+
32
+ throw e ;
33
+ }
17
34
18
- constructor ( entry : FileEntry ) {
19
- this . _original = Buffer . from ( entry . content ) ;
20
- this . _content = UpdateBufferBase . create ( entry . path , entry . content ) ;
21
- this . _path = entry . path ;
35
+ this . _path = path ;
36
+ this . content = new MagicString ( text ) ;
22
37
}
23
38
24
39
static createFromFileEntry ( entry : FileEntry ) : UpdateRecorderBase {
@@ -28,62 +43,56 @@ export class UpdateRecorderBase implements UpdateRecorder {
28
43
29
44
// Check if we're BOM.
30
45
if ( c0 == 0xef && c1 == 0xbb && c2 == 0xbf ) {
31
- return new UpdateRecorderBom ( entry ) ;
46
+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-8' , true ) ;
32
47
} else if ( c0 === 0xff && c1 == 0xfe ) {
33
- return new UpdateRecorderBom ( entry ) ;
48
+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-16le' , true ) ;
34
49
} else if ( c0 === 0xfe && c1 == 0xff ) {
35
- return new UpdateRecorderBom ( entry ) ;
50
+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-16be' , true ) ;
36
51
}
37
52
38
- return new UpdateRecorderBase ( entry ) ;
53
+ return new UpdateRecorderBase ( entry . content , entry . path ) ;
39
54
}
40
55
41
56
get path ( ) {
42
57
return this . _path ;
43
58
}
44
59
60
+ protected _assertIndex ( index : number ) {
61
+ if ( index < 0 || index > this . content . original . length ) {
62
+ throw new IndexOutOfBoundException ( index , 0 , this . content . original . length ) ;
63
+ }
64
+ }
65
+
45
66
// These just record changes.
46
67
insertLeft ( index : number , content : Buffer | string ) : UpdateRecorder {
47
- this . _content . insertLeft ( index , typeof content == 'string' ? Buffer . from ( content ) : content ) ;
68
+ this . _assertIndex ( index ) ;
69
+ this . content . appendLeft ( index , content . toString ( ) ) ;
48
70
49
71
return this ;
50
72
}
51
73
52
74
insertRight ( index : number , content : Buffer | string ) : UpdateRecorder {
53
- this . _content . insertRight ( index , typeof content == 'string' ? Buffer . from ( content ) : content ) ;
75
+ this . _assertIndex ( index ) ;
76
+ this . content . appendRight ( index , content . toString ( ) ) ;
54
77
55
78
return this ;
56
79
}
57
80
58
81
remove ( index : number , length : number ) : UpdateRecorder {
59
- this . _content . remove ( index , length ) ;
82
+ this . _assertIndex ( index ) ;
83
+ this . content . remove ( index , index + length ) ;
60
84
61
85
return this ;
62
86
}
63
87
64
88
apply ( content : Buffer ) : Buffer {
65
- if ( ! content . equals ( this . _content . original ) ) {
89
+ if ( ! content . equals ( this . data ) ) {
66
90
throw new ContentHasMutatedException ( this . path ) ;
67
91
}
68
92
69
- return this . _content . generate ( ) ;
70
- }
71
- }
72
-
73
- export class UpdateRecorderBom extends UpdateRecorderBase {
74
- constructor ( entry : FileEntry , private _delta = 1 ) {
75
- super ( entry ) ;
76
- }
77
-
78
- override insertLeft ( index : number , content : Buffer | string ) {
79
- return super . insertLeft ( index + this . _delta , content ) ;
80
- }
81
-
82
- override insertRight ( index : number , content : Buffer | string ) {
83
- return super . insertRight ( index + this . _delta , content ) ;
84
- }
93
+ // Schematics only support writing UTF-8 text
94
+ const result = Buffer . from ( ( this . bom ? '\uFEFF' : '' ) + this . content . toString ( ) , 'utf-8' ) ;
85
95
86
- override remove ( index : number , length : number ) {
87
- return super . remove ( index + this . _delta , length ) ;
96
+ return result ;
88
97
}
89
98
}
0 commit comments