1
+ "use strict" ;
2
+
3
+ var diffingPlugin = require ( './diffing-broccoli-plugin' ) ;
4
+ var path = require ( 'path' ) ;
5
+ var fs = require ( 'fs' ) ;
6
+ var crypto = require ( 'crypto' ) ;
7
+
8
+ var FILE_ENCODING = { encoding : 'utf-8' } ;
9
+ var MANIFEST_FILE = 'manifest.appcache' ;
10
+ var FILE_HASH_PREFIX = '# sw.file.hash:' ;
11
+
12
+ class DiffingSWManifest {
13
+ constructor ( inputPath , cachePath , options ) {
14
+ this . inputPath = inputPath ;
15
+ this . cachePath = cachePath ;
16
+ this . options = options ;
17
+ this . firstBuild = true ;
18
+ }
19
+
20
+ rebuild ( diff ) {
21
+ var manifest = { } ;
22
+ if ( this . firstBuild ) {
23
+ this . firstBuild = false ;
24
+ } else {
25
+ // Read manifest from disk.
26
+ manifest = this . readManifestFromCache ( ) ;
27
+ }
28
+
29
+ // Remove manifest entries for files that are no longer present.
30
+ diff . removedPaths . forEach ( ( file ) => delete manifest [ file ] ) ;
31
+
32
+ // Merge the lists of added and changed paths and update their hashes in the manifest.
33
+ [ ]
34
+ . concat ( diff . addedPaths )
35
+ . concat ( diff . changedPaths )
36
+ . filter ( ( file ) => file !== MANIFEST_FILE )
37
+ . forEach ( ( file ) => manifest [ file ] = this . computeFileHash ( file ) ) ;
38
+ var manifestPath = path . join ( this . cachePath , MANIFEST_FILE ) ;
39
+ fs . writeFileSync ( manifestPath , this . generateManifest ( manifest ) ) ;
40
+ }
41
+
42
+ // Compute the hash of the given relative file.
43
+ computeFileHash ( file ) {
44
+ var contents = fs . readFileSync ( path . join ( this . inputPath , file ) ) ;
45
+ return crypto
46
+ . createHash ( 'sha1' )
47
+ . update ( contents )
48
+ . digest ( 'hex' ) ;
49
+ }
50
+
51
+ // Compute the hash of the bundle from the names and hashes of all included files.
52
+ computeBundleHash ( files , manifest ) {
53
+ var hash = crypto . createHash ( 'sha1' ) ;
54
+ files . forEach ( ( file ) => hash . update ( manifest [ file ] + ':' + file ) ) ;
55
+ return hash . digest ( 'hex' ) ;
56
+ }
57
+
58
+ // Generate the string contents of the manifest.
59
+ generateManifest ( manifest ) {
60
+ var files = Object . keys ( manifest ) . sort ( ) ;
61
+ var bundleHash = this . computeBundleHash ( files , manifest ) ;
62
+ var contents = files
63
+ . map ( ( file ) => `# sw.file.hash: ${ this . computeFileHash ( file ) } \n/${ file } ` )
64
+ . join ( '\n' ) ;
65
+ return `CACHE MANIFEST
66
+ # sw.bundle: ng-cli
67
+ # sw.version: ${ bundleHash }
68
+ ${ contents }
69
+ ` ;
70
+ }
71
+
72
+ // Read the manifest from the cache and split it out into a dict of files to hashes.
73
+ readManifestFromCache ( ) {
74
+ var contents = fs . readFileSync ( path . join ( this . cachePath , MANIFEST_FILE ) , FILE_ENCODING ) ;
75
+ var manifest = { } ;
76
+ var hash = null ;
77
+ contents
78
+ . split ( '\n' )
79
+ . map ( ( line ) => line . trim ( ) )
80
+ . filter ( ( line ) => line !== 'CACHE MANIFEST' )
81
+ . filter ( ( line ) => line !== '' )
82
+ . filter ( ( line ) => ! line . startsWith ( '#' ) || line . startsWith ( '# sw.' ) )
83
+ . forEach ( ( line ) => {
84
+ if ( line . startsWith ( FILE_HASH_PREFIX ) ) {
85
+ // This is a hash prefix for the next file in the list.
86
+ hash = line . substring ( FILE_HASH_PREFIX . length ) . trim ( ) ;
87
+ } else if ( line . startsWith ( '/' ) ) {
88
+ // This is a file belonging to the application.
89
+ manifest [ line . substring ( 1 ) ] = hash ;
90
+ hash = null ;
91
+ }
92
+ } ) ;
93
+ return manifest ;
94
+ }
95
+ }
96
+
97
+ Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
98
+ exports . default = diffingPlugin . wrapDiffingPlugin ( DiffingSWManifest ) ;
0 commit comments