Repository: GoogleChrome/sw-precache
Pull request #297 (2017-05-12 20:38:20)

dynamicUrlToDependencies: Support Buffers alongside strings
I need this to declare dependencies that aren't text based.

googlebot: Thanks for your pull request.  It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please visit <https://cla.developers.google.com/> to sign.**

Once you've signed, please reply here (e.g. `I signed it!`) and we'll verify.  Thanks.

---

- If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address.  Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).
- If you signed the CLA as a corporation, please let us know the company's name.

<!-- need_sender_cla -->
papandreou: I signed it!
googlebot: CLAs look good, thanks!

<!-- ok -->
papandreou: Rebased and fixed conflicts.

Ping?
jeffposnick: Thanks for the contribution!

Patch:
diff --git a/README.md b/README.md
index 1efffbe..82feb1b 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ by [Huang Xuan](https://twitter.com/Huxpro).
     - [clientsClaim [Boolean]](#clientsclaim-boolean)
     - [directoryIndex [String]](#directoryindex-string)
     - [dontCacheBustUrlsMatching [Regex]](#dontcachebusturlsmatching-regex)
-    - [dynamicUrlToDependencies [Object&#x27e8;String,Array&#x27e8;String&#x27e9;&#x27e9;]](#dynamicurltodependencies-objectstringarraystring)
+    - [dynamicUrlToDependencies [Object&#x27e8;String,Buffer,Array&#x27e8;String&#x27e9;&#x27e9;]](#dynamicurltodependencies-objectstringarraystring)
     - [handleFetch [boolean]](#handlefetch-boolean)
     - [ignoreUrlParametersMatching [Array&#x27e8;Regex&#x27e9;]](#ignoreurlparametersmatching-arrayregex)
     - [importScripts [Array&#x27e8;String&#x27e9;]](#importscripts-arraystring)
@@ -364,7 +364,7 @@ the entire request URL. As of v5.0.0, it only matches against the URL's
 
 _Default_: not set
 
-#### dynamicUrlToDependencies [Object&#;String,Array&#;String&#;&#;]
+#### dynamicUrlToDependencies [Object&#x27e8;String,Buffer,Array&#x27e8;String&#x27e9;&#x27e9;]
 Maps a dynamic URL string to an array of all the files that URL's contents
 depend on. E.g., if the contents of `/pages/home` are generated server-side via
 the templates `layout.jade` and `home.jade`, then specify `'/pages/home':
@@ -372,9 +372,9 @@ the templates `layout.jade` and `home.jade`, then specify `'/pages/home':
 `/pages/home` has changed will depend on the hashes of both `layout.jade` and
 `home.jade`.
 
-As of v5.1.0, and alternative value for the mapping is supported as well. You can now specify
-a string rather than an array of file names. If you use this option, then the
-hash of the string will be used to determine whether the URL used as a key has changed.
+An alternative value for the mapping is supported as well. You can specify
+a string or a Buffer instance rather than an array of file names. If you use this option, then the
+hash of the string/Buffer will be used to determine whether the URL used as a key has changed.
 For example, `'/pages/dynamic': dynamicStringValue` could be used if the contents of
 `/pages/dynamic` changes whenever the string stored in `dynamicStringValue` changes.
 
@@ -388,7 +388,7 @@ would always be served from the service worker cache.
 
 _Default_: `true`
 
-#### ignoreUrlParametersMatching [Array&#;Regex&#;]
+#### ignoreUrlParametersMatching [Array&#x27e8;Regex&#x27e9;]
 `sw-precache` finds matching cache entries by doing a comparison with the full request URL. It's
 common for sites to support URL query parameters that don't affect the site's content and should
 be effectively ignored for the purposes of cache matching. One example is the
@@ -399,7 +399,7 @@ To ignore all parameters, use `[/./]`. To take all parameters into account when
 
 _Default_: `[/^utm_/]`
 
-#### importScripts [Array&#;String&#;]
+#### importScripts [Array&#x27e8;String&#x27e9;]
 Writes calls to [`importScripts()`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage#Importing_scripts_and_libraries)
 to the resulting service worker to import the specified scripts.
 
@@ -419,7 +419,7 @@ Sets the maximum allowed size for a file in the precache list.
 _Default_: `2097152` (2 megabytes)
 
 #### navigateFallback [String]
-Sets an HTML document to use as a fallback for URLs not found in the `sw-precahe` cache. This
+Sets an HTML document to use as a fallback for URLs not found in the `sw-precache` cache. This
 fallback URL needs to be cached via `staticFileGlobs` or `dynamicUrlToDependencies` otherwise it
 won't work.
 
@@ -447,7 +447,7 @@ the request is a navigation.
 
 _Default_: `''`
 
-#### navigateFallbackWhitelist [Array&#;RegExp&#;]
+#### navigateFallbackWhitelist [Array&#x27e8;RegExp&#x27e9;]
 Works to limit the effect of `navigateFallback`, so that the fallback only
 applies to requests for URLs with paths that match at least one
 [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp).
@@ -480,7 +480,7 @@ and replace it with '/public/'.
 
 _Default_: `''`
 
-#### runtimeCaching [Array&#;Object&#;]
+#### runtimeCaching [Array&#x27e8;Object&#x27e8;]
 Configures runtime caching for dynamic content. If you use this option, the `sw-toolbox`
 library configured with the caching strategies you specify will automatically be included in
 your generated service worker file.
@@ -541,7 +541,7 @@ until they're needed at runtime.
 
 _Default_: `true`
 
-#### staticFileGlobs [Array&#;String&#;]
+#### staticFileGlobs [Array&#x27e8;String&#x27e9;]
 An array of one or more string patterns that will be passed in to
 [`glob`](https://github.com/isaacs/node-glob).
 All files matching these globs will be automatically precached by the generated service worker.
diff --git a/lib/sw-precache.js b/lib/sw-precache.js
index 5d6c7cc..82875cb 100644
--- a/lib/sw-precache.js
+++ b/lib/sw-precache.js
@@ -194,15 +194,16 @@ function generate(params, callback) {
     Object.keys(params.dynamicUrlToDependencies).forEach(function(dynamicUrl) {
       var dependency = params.dynamicUrlToDependencies[dynamicUrl];
       var isString = typeof dependency === 'string';
+      var isBuffer = Buffer.isBuffer(dependency);
 
-      if (!Array.isArray(dependency) && !isString) {
+      if (!Array.isArray(dependency) && !isString && !isBuffer) {
         throw Error(util.format(
           'The value for the dynamicUrlToDependencies.%s ' +
-          'option must be an Array or a String.',
+          'option must be an Array, a Buffer, or a String.',
           dynamicUrl));
       }
 
-      if (isString) {
+      if (isString || isBuffer) {
         cumulativeSize += dependency.length;
         relativeUrlToHash[dynamicUrl] = getHash(dependency);
       } else {
@@ -242,6 +243,10 @@ function generate(params, callback) {
           params.logger(util.format(
             'Caching dynamic URL "%s" with dependency on user-supplied string',
             dynamicUrl));
+        } else if (isBuffer) {
+          params.logger(util.format(
+            'Caching dynamic URL "%s" with dependency on user-supplied buffer',
+            dynamicUrl));
         } else {
           params.logger(util.format(
             'Caching dynamic URL "%s" with dependencies on %j',


Test patch:
diff --git a/test/test.js b/test/test.js
index e033baf..8e1597f 100644
--- a/test/test.js
+++ b/test/test.js
@@ -207,6 +207,34 @@ describe('sw-precache core functionality', function() {
     });
   });
 
+  describe('with dynamicUrlToDependencies', function() {
+    it('should allow passing a string value', function() {
+      var config = {
+        logger: NOOP,
+        dynamicUrlToDependencies: {
+          'foo.png': 'abc'
+        }
+      };
+
+      return generate(config).then(function(responseString) {
+        assert.notEqual(responseString.indexOf('["foo.png","900150983cd24fb0d6963f7d28e17f72"]'), -1);
+      });
+    });
+
+    it('should allow passing a Buffer instance', function() {
+      var config = {
+        logger: NOOP,
+        dynamicUrlToDependencies: {
+          'foo.png': new Buffer([0x00, 0x01, 0x02])
+        }
+      };
+
+      return generate(config).then(function(responseString) {
+        assert.notEqual(responseString.indexOf('["foo.png","b95f67f61ebb03619622d798f45fc2d3"]'), -1);
+      });
+    });
+  });
+
   after(function() {
     fs.unlinkSync(TEMP_FILE);
   });