UNPKG

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