123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- "use strict";
- var etag = require("etag");
- var fresh = require("fresh");
- var fs = require("fs");
- var path = require("path");
- var zlib = require("zlib");
- var minifiedScript = path.join(__dirname, "dist", "index.js");
- var unminifiedScript = path.join(__dirname, "dist", "index.js");
- /**
- * Does the current request support compressed encoding?
- * @param {Object} req
- * @returns {boolean}
- */
- function supportsGzip(req) {
- var accept = req.headers["accept-encoding"];
- return accept && accept.indexOf("gzip") > -1;
- }
- /**
- * Set headers on the response
- * @param {Object} res
- * @param {String} body
- */
- function setHeaders(res, body) {
- res.setHeader("Cache-Control", "public, max-age=0");
- res.setHeader("Content-Type", "text/javascript");
- res.setHeader("ETag", etag(body));
- }
- /**
- * @param {Object} req
- * @returns {String}
- */
- function isConditionalGet(req) {
- return req.headers["if-none-match"] || req.headers["if-modified-since"];
- }
- /**
- * Return a not-modified response
- * @param {Object} res
- */
- function notModified(res) {
- res.removeHeader("Content-Type");
- res.statusCode = 304;
- res.end();
- }
- function processItems(items) {
- return [].concat(items)
- .filter(Boolean)
- .reduce((stringOutput, item) => {
- if (typeof item === 'string') {
- return stringOutput + item;
- }
- if (typeof item === 'function') {
- return stringOutput + item();
- }
- return stringOutput;
- }, "");
- }
- /**
- * Public method for returning either a middleware fn
- * or the content as a string
- * @param {Object} options
- * @param requestBody
- * @param {String} type - either `file` or `middleware`
- * @returns {*}
- */
- function init(options, requestBody, type) {
- /**
- * If the user asked for a file, simply return the string.
- */
- if (type && type === "file") {
- return processItems(requestBody);
- }
- /**
- * Otherwise return a function to be used a middleware
- */
- return function(req, res) {
- /**
- * default to using the uncompressed string
- * @type {String}
- */
- var output = processItems(requestBody);
- /**
- * Set the appropriate headers for caching
- */
- setHeaders(res, output);
- var resHeaders = res.getHeaders ? res.getHeaders() : res._headers;
- if (isConditionalGet(req) && fresh(req.headers, resHeaders)) {
- return notModified(res);
- }
- /**
- * If gzip is supported, compress the string once
- * and save for future requests
- */
- if (supportsGzip(req)) {
- res.setHeader("Content-Encoding", "gzip");
- var buf = Buffer.from(output, "utf-8");
- zlib.gzip(buf, function(_, result) {
- res.end(result);
- });
- } else {
- res.end(output);
- }
- };
- }
- module.exports.middleware = init;
- module.exports.plugin = init;
- module.exports.minified = function() {
- return fs.readFileSync(minifiedScript, "utf8");
- };
- module.exports.unminified = function() {
- return fs.readFileSync(unminifiedScript, "utf8");
- };
|