66 * found in the LICENSE file at https://angular.io/license
77 */
88
9+ import MagicString from 'magic-string' ;
910import { ContentHasMutatedException } from '../exception/exception' ;
10- import { UpdateBufferBase } from '../utility/update-buffer' ;
11+ import { IndexOutOfBoundException } from '../utility/update-buffer' ;
1112import { FileEntry , UpdateRecorder } from './interface' ;
1213
1314export class UpdateRecorderBase implements UpdateRecorder {
1415 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+ }
1734
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 ) ;
2237 }
2338
2439 static createFromFileEntry ( entry : FileEntry ) : UpdateRecorderBase {
@@ -28,62 +43,56 @@ export class UpdateRecorderBase implements UpdateRecorder {
2843
2944 // Check if we're BOM.
3045 if ( c0 == 0xef && c1 == 0xbb && c2 == 0xbf ) {
31- return new UpdateRecorderBom ( entry ) ;
46+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-8' , true ) ;
3247 } else if ( c0 === 0xff && c1 == 0xfe ) {
33- return new UpdateRecorderBom ( entry ) ;
48+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-16le' , true ) ;
3449 } else if ( c0 === 0xfe && c1 == 0xff ) {
35- return new UpdateRecorderBom ( entry ) ;
50+ return new UpdateRecorderBase ( entry . content , entry . path , 'utf-16be' , true ) ;
3651 }
3752
38- return new UpdateRecorderBase ( entry ) ;
53+ return new UpdateRecorderBase ( entry . content , entry . path ) ;
3954 }
4055
4156 get path ( ) {
4257 return this . _path ;
4358 }
4459
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+
4566 // These just record changes.
4667 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 ( ) ) ;
4870
4971 return this ;
5072 }
5173
5274 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 ( ) ) ;
5477
5578 return this ;
5679 }
5780
5881 remove ( index : number , length : number ) : UpdateRecorder {
59- this . _content . remove ( index , length ) ;
82+ this . _assertIndex ( index ) ;
83+ this . content . remove ( index , index + length ) ;
6084
6185 return this ;
6286 }
6387
6488 apply ( content : Buffer ) : Buffer {
65- if ( ! content . equals ( this . _content . original ) ) {
89+ if ( ! content . equals ( this . data ) ) {
6690 throw new ContentHasMutatedException ( this . path ) ;
6791 }
6892
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' ) ;
8595
86- override remove ( index : number , length : number ) {
87- return super . remove ( index + this . _delta , length ) ;
96+ return result ;
8897 }
8998}
0 commit comments