UNPKG

3.35 kBJavaScriptView Raw
1'use strict';
2
3var base64 = require('base64-js');
4var crypto = require('crypto');
5var fs = require('fs');
6var path = require('path');
7var walk = require('walk');
8
9var MAX_FILE_SIZE_BYTES = 15728640; // 15MB.
10
11module.exports = {
12 sha256hash: function sha256hash(content) {
13 return crypto.createHash('sha256').update(content, 'utf8').digest('hex');
14 },
15 base64encode: function base64encode(content) {
16 return base64.fromByteArray(new Buffer(content));
17 },
18 getMissingResources: function getMissingResources(response) {
19 return response && response.body && response.body.data && response.body.data.relationships && response.body.data.relationships['missing-resources'] && response.body.data.relationships['missing-resources'].data || [];
20 },
21
22
23 // Synchronously walk a directory of compiled assets, read each file and calculate its SHA 256
24 // hash, and create an array of Resource objects.
25 gatherBuildResources: function gatherBuildResources(percyClient, rootDir) {
26 var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
27
28 // The base of the URL that will be prepended to every resource URL, such as "/assets".
29 options.baseUrlPath = options.baseUrlPath || '';
30 options.skippedPathRegexes = options.skippedPathRegexes || [];
31 options.followLinks = options.followLinks || true;
32
33 var resources = [];
34
35 var fileWalker = function fileWalker(root, fileStats, next) {
36 var absolutePath = path.join(root, fileStats.name);
37 var resourceUrl = absolutePath.replace(rootDir, '');
38
39 if (path.sep == '\\') {
40 // Windows support: transform filesystem backslashes into forward-slashes for the URL.
41 resourceUrl = resourceUrl.replace(/\\/g, '/');
42 }
43
44 // Prepend the baseUrlPath if it is given. We normalize it to make sure it does not have
45 // a trailing slash, or it's a blank string.
46 var normalizedBaseUrlPath = (options.baseUrlPath || '/').replace(/\/$/, '');
47 resourceUrl = normalizedBaseUrlPath + resourceUrl;
48
49 // Skip excluded paths.
50 for (var i in options.skippedPathRegexes) {
51 if (resourceUrl.match(options.skippedPathRegexes[i])) {
52 next();
53 return;
54 }
55 }
56
57 // Skip large files.
58 if (fs.statSync(absolutePath)['size'] > MAX_FILE_SIZE_BYTES) {
59 // eslint-disable-next-line no-console
60 console.warn('\n[percy][WARNING] Skipping large build resource: ', resourceUrl);
61 return;
62 }
63
64 // Note: this is synchronous and potentially memory intensive, but we don't keep a
65 // reference to the content around so each should be garbage collected. Reevaluate?
66 var content = fs.readFileSync(absolutePath);
67 var sha = crypto.createHash('sha256').update(content).digest('hex');
68
69 var resource = percyClient.makeResource({
70 resourceUrl: encodeURI(resourceUrl),
71 sha: sha,
72 localPath: absolutePath
73 });
74
75 resources.push(resource);
76 next();
77 };
78
79 var walkOptions = {
80 // Follow symlinks because assets may be just symlinks.
81 followLinks: options.followLinks,
82 listeners: {
83 file: fileWalker
84 }
85 };
86 walk.walkSync(rootDir, walkOptions);
87
88 return resources;
89 },
90 reverseString: function reverseString(str) {
91 return str.split('').reverse().join('');
92 }
93};
\No newline at end of file