2024-01-17 15:40:27 -05:00
|
|
|
|
const glob = require('glob');
|
|
|
|
|
const path = require('path');
|
2017-04-25 13:18:13 -04:00
|
|
|
|
|
2024-01-17 15:40:27 -05:00
|
|
|
|
const FastlyConfigMethods = {
|
2017-04-25 13:18:13 -04:00
|
|
|
|
/*
|
|
|
|
|
* Given the relative path to the static directory, return an array of
|
|
|
|
|
* patterns matching the files and directories there.
|
|
|
|
|
*/
|
|
|
|
|
getStaticPaths: function (rootDir, pathToStatic) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
const staticPaths = glob.sync(path.resolve(rootDir, pathToStatic));
|
|
|
|
|
return staticPaths.filter(pathName =>
|
2017-04-25 13:18:13 -04:00
|
|
|
|
// Exclude view html, resolve everything else in the build
|
2024-01-17 15:40:27 -05:00
|
|
|
|
path.extname(pathName) !== '.html'
|
|
|
|
|
).map(pathName => {
|
2017-04-25 13:18:13 -04:00
|
|
|
|
// Reduce absolute path to relative paths like '/js'
|
2024-01-17 15:40:27 -05:00
|
|
|
|
const base = path.dirname(path.resolve(rootDir, pathToStatic));
|
2017-04-25 13:18:13 -04:00
|
|
|
|
return pathName.replace(base, '') + (path.extname(pathName) ? '' : '/');
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Given a list of express routes, return a list of patterns to match
|
|
|
|
|
* the express route and a static view file associated with the route
|
|
|
|
|
*/
|
|
|
|
|
getViewPaths: function (routes) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return routes.reduce((paths, route) => {
|
|
|
|
|
const p = route.routeAlias || route.pattern;
|
2018-01-30 11:53:12 -05:00
|
|
|
|
if (paths.indexOf(p) === -1) {
|
|
|
|
|
paths.push(p);
|
2017-04-25 13:18:13 -04:00
|
|
|
|
}
|
|
|
|
|
return paths;
|
|
|
|
|
}, []);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/*
|
2017-05-24 08:51:28 -04:00
|
|
|
|
* Translate an express-style pattern to regex one in two ways:
|
|
|
|
|
*
|
|
|
|
|
* 1. /path/:arg/ – all :arg's become .+?
|
|
|
|
|
* 2. /path/:arg([regex]) – :arg is removed, leaving just /path/([regex])
|
2017-04-25 13:18:13 -04:00
|
|
|
|
*/
|
|
|
|
|
expressPatternToRegex: function (pattern) {
|
2018-01-30 11:53:12 -05:00
|
|
|
|
pattern = pattern.replace(/(:\w+)(\([^)]+\))/gi, '$2');
|
2017-05-18 13:57:49 -04:00
|
|
|
|
return pattern.replace(/(:\w+)/gi, '.+?');
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Given a list of patterns for paths, OR all of them together into one
|
|
|
|
|
* string suitable for a Fastly condition
|
|
|
|
|
*/
|
|
|
|
|
pathsToCondition: function (paths) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return `req.url~"^(${
|
|
|
|
|
paths.reduce((conditionString, pattern) => conditionString + (conditionString ? '|' : '') + pattern, '')
|
|
|
|
|
})"`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Helper method to NOT a condition statement
|
|
|
|
|
*/
|
|
|
|
|
negateConditionStatement: function (statement) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return `!(${statement})`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Combine static paths, routes, and any additional paths to a single
|
|
|
|
|
* fastly condition to match req.url
|
|
|
|
|
*/
|
|
|
|
|
getAppRouteCondition: function (pathToStatic, routes, additionalPaths, rootDir) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
const staticPaths = FastlyConfigMethods.getStaticPaths(rootDir, pathToStatic);
|
|
|
|
|
const viewPaths = FastlyConfigMethods.getViewPaths(routes);
|
|
|
|
|
const allPaths = [].concat(staticPaths, viewPaths, additionalPaths);
|
2017-04-25 13:18:13 -04:00
|
|
|
|
return FastlyConfigMethods.pathsToCondition(allPaths);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getConditionNameForRoute: function (route, type) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return `routes/${route.pattern} (${type})`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getHeaderNameForRoute: function (route) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
if (route.name) return `rewrites/${route.name}`;
|
|
|
|
|
if (route.redirect) return `redirects/${route.pattern}`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getResponseNameForRoute: function (route) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return `redirects/${route.pattern}`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
},
|
|
|
|
|
|
2018-01-30 11:53:12 -05:00
|
|
|
|
/*
|
2017-04-25 13:18:13 -04:00
|
|
|
|
* Returns custom vcl configuration as a string that sets the varnish
|
|
|
|
|
* Time to Live (TTL) for responses that come from s3.
|
|
|
|
|
*
|
|
|
|
|
* @param {string} condition condition under which the response should be set
|
|
|
|
|
*/
|
|
|
|
|
setResponseTTL: function (condition) {
|
2024-01-17 15:40:27 -05:00
|
|
|
|
return `${'' +
|
|
|
|
|
'if ('}${condition}) {\n` +
|
|
|
|
|
` if (req.url ~ "^(/projects/|/fragment/account-nav.json|/session/)" && ` +
|
|
|
|
|
`!req.http.Cookie:scratchsessionsid) {\n` +
|
|
|
|
|
` set beresp.http.Vary = "Accept-Encoding, Accept-Language";\n` +
|
|
|
|
|
` unset beresp.http.set-cookie;\n` +
|
|
|
|
|
` return(deliver);\n` +
|
|
|
|
|
` } else {\n` +
|
|
|
|
|
` set beresp.ttl = 0s;\n` +
|
|
|
|
|
` set beresp.grace = 0s;\n` +
|
|
|
|
|
` return(pass);\n` +
|
|
|
|
|
` }\n` +
|
|
|
|
|
`}\n`;
|
2017-04-25 13:18:13 -04:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
module.exports = FastlyConfigMethods;
|