mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-27 17:30:28 -04:00
remove unused lambda functions from production
This commit is contained in:
parent
42355c76ec
commit
83d88f0f77
@ -1,390 +0,0 @@
|
||||
/*! Simple Analytics - Privacy friendly analytics (docs.simpleanalytics.com/script; 2020-06-29; bb25) */
|
||||
// https://github.com/simpleanalytics/scripts/blob/21632405db31416d07006226cfb52cd348f73691/src/default.js
|
||||
|
||||
(function (window, baseUrl) {
|
||||
if (!window) return;
|
||||
|
||||
try {
|
||||
// Generate the needed variables, this seems like a lot of repetition, but it
|
||||
// makes our script availble for multple destination which prevents us to
|
||||
// need multiple scripts. The minified version stays small.
|
||||
var version = 4;
|
||||
var functionName = "sa_event";
|
||||
var pageviewsText = "pageview";
|
||||
var https = "https:";
|
||||
var protocol = https + "//";
|
||||
var slash = "/";
|
||||
var fullApiUrl = protocol + baseUrl;
|
||||
var doc = window.document;
|
||||
var nav = window.navigator;
|
||||
var screen = window.screen;
|
||||
var loc = window.location;
|
||||
var locationHostname = loc.hostname;
|
||||
var userAgent = nav.userAgent;
|
||||
var documentElement = doc.documentElement || {};
|
||||
var addEventListenerFunc = window.addEventListener;
|
||||
var encodeURIComponentFunc = encodeURIComponent;
|
||||
var decodeURIComponentFunc = decodeURIComponent;
|
||||
// var stringify = JSON.stringify;
|
||||
var thousand = 1000;
|
||||
var undefinedVar = undefined;
|
||||
var language = "language";
|
||||
var Height = "Height";
|
||||
var Width = "Width";
|
||||
var scroll = "scroll";
|
||||
var scrollHeight = scroll + Height;
|
||||
var offsetHeight = "offset" + Height;
|
||||
var clientHeight = "client" + Height;
|
||||
var clientWidth = "client" + Width;
|
||||
|
||||
var payload = {
|
||||
version: version,
|
||||
};
|
||||
|
||||
var options = {
|
||||
hostname: locationHostname,
|
||||
functionName: functionName,
|
||||
};
|
||||
|
||||
var bot = /(bot|spider|crawl)/i.test(userAgent);
|
||||
if (bot) payload.bot = true;
|
||||
|
||||
payload.hostname = options.hostname;
|
||||
|
||||
// A simple log function so the user knows why a request is not being sent, uncomment for debugging
|
||||
// var warn = function (message) {
|
||||
// if (console && console.warn) console.warn("Simple Analytics:", message);
|
||||
// };
|
||||
|
||||
var now = Date.now;
|
||||
|
||||
var uuid = function () {
|
||||
var cryptoObject = window.crypto || window.msCrypto;
|
||||
var emptyUUID = [1e7] + -1e3 + -4e3 + -8e3 + -1e11;
|
||||
var uuidRegex = /[018]/g;
|
||||
|
||||
try {
|
||||
return emptyUUID.replace(uuidRegex, function (c) {
|
||||
return (c ^ (cryptoObject.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16); // eslint-disable-line compat/compat
|
||||
});
|
||||
} catch (error) {
|
||||
return emptyUUID.replace(uuidRegex, function (c) {
|
||||
var r = (Math.random() * 16) | 0,
|
||||
v = c < 2 ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var assign = function () {
|
||||
var to = {};
|
||||
for (var index = 0; index < arguments.length; index++) {
|
||||
var nextSource = arguments[index];
|
||||
if (nextSource) {
|
||||
for (var nextKey in nextSource) {
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
};
|
||||
|
||||
var getParams = function (regex) {
|
||||
// From the search we grab the utm_source and ref and save only that
|
||||
var matches = loc.search.match(new RegExp("[?&](" + regex + ")=([^?&]+)", "gi"));
|
||||
var match = matches
|
||||
? matches.map(function (m) {
|
||||
return m.split("=")[1];
|
||||
})
|
||||
: [];
|
||||
if (match && match[0]) return match[0];
|
||||
};
|
||||
|
||||
// Send data via image
|
||||
function sendData(data, callback) {
|
||||
data = assign(payload, data);
|
||||
var image = new Image();
|
||||
if (callback) {
|
||||
image.onerror = callback;
|
||||
image.onload = callback;
|
||||
}
|
||||
image.src =
|
||||
fullApiUrl +
|
||||
"?" +
|
||||
Object.keys(data)
|
||||
.filter(function (key) {
|
||||
return data[key] != undefinedVar;
|
||||
})
|
||||
.map(function (key) {
|
||||
return encodeURIComponentFunc(key) + "=" + encodeURIComponentFunc(data[key]);
|
||||
})
|
||||
.join("&");
|
||||
}
|
||||
|
||||
/** if duration **/
|
||||
var duration = "duration";
|
||||
var start = now();
|
||||
/** endif **/
|
||||
|
||||
/** if scroll **/
|
||||
var scrolled = 0;
|
||||
/** endif **/
|
||||
|
||||
// This code could error on not having resolvedOptions in the Android Webview, that's why we use try...catch
|
||||
var timezone;
|
||||
try {
|
||||
timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; // eslint-disable-line compat/compat
|
||||
} catch (e) {
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
// When a customer overwrites the hostname, we need to know what the original
|
||||
// hostname was to hide that domain from referrer traffic
|
||||
if (options.hostname !== locationHostname) payload.hostname_original = locationHostname;
|
||||
|
||||
var page = {};
|
||||
var lastPageId = uuid();
|
||||
var lastSendPath;
|
||||
|
||||
// We don't want to end up with sensitive data so we clean the referrer URL
|
||||
var referrer =
|
||||
(doc.referrer || "")
|
||||
.replace(locationHostname, locationHostname)
|
||||
.replace(/^https?:\/\/((m|l|w{2,3}([0-9]+)?)\.)?([^?#]+)(.*)$/, "$4")
|
||||
.replace(/^([^/]+)$/, "$1") || undefinedVar;
|
||||
|
||||
// The prefix utm_ is optional
|
||||
var utmRegexPrefix = "(utm_)?";
|
||||
var source = {
|
||||
source: getParams(utmRegexPrefix + "source|ref"),
|
||||
medium: getParams(utmRegexPrefix + "medium"),
|
||||
campaign: getParams(utmRegexPrefix + "campaign"),
|
||||
term: getParams(utmRegexPrefix + "term"),
|
||||
content: getParams(utmRegexPrefix + "content"),
|
||||
referrer: referrer,
|
||||
};
|
||||
|
||||
// We don't put msHidden in if duration block, because it's used outside of that functionality
|
||||
var msHidden = 0;
|
||||
|
||||
/** if duration **/
|
||||
var hiddenStart;
|
||||
window.addEventListener(
|
||||
"visibilitychange",
|
||||
function () {
|
||||
if (doc.hidden) hiddenStart = now();
|
||||
else msHidden += now() - hiddenStart;
|
||||
},
|
||||
false
|
||||
);
|
||||
/** endif **/
|
||||
|
||||
// var sendBeaconText = "sendBeacon";
|
||||
|
||||
var sendOnLeave = function (id, push) {
|
||||
var append = { type: "append", original_id: push ? id : lastPageId };
|
||||
|
||||
/** if duration **/
|
||||
append[duration] = Math.round((now() - start + msHidden) / thousand);
|
||||
msHidden = 0;
|
||||
start = now();
|
||||
/** endif **/
|
||||
|
||||
/** if scroll **/
|
||||
append.scrolled = Math.max(0, scrolled, position());
|
||||
/** endif **/
|
||||
|
||||
// if (push || !(sendBeaconText in nav)) {
|
||||
sendData(append);
|
||||
// } else {
|
||||
// nav[sendBeaconText](fullApiUrl + "/append", stringify(assign(payload, append)));
|
||||
// }
|
||||
};
|
||||
|
||||
// https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event
|
||||
var terminationEvent = "onpagehide" in self ? "pagehide" : "unload";
|
||||
addEventListenerFunc(terminationEvent, sendOnLeave, false);
|
||||
// addEventListenerFunc("unload", sendOnLeave, false);
|
||||
|
||||
/** if scroll **/
|
||||
var body = doc.body || {};
|
||||
var position = function () {
|
||||
try {
|
||||
var documentClientHeight = documentElement[clientHeight] || 0;
|
||||
var height = Math.max(
|
||||
body[scrollHeight] || 0,
|
||||
body[offsetHeight] || 0,
|
||||
documentElement[clientHeight] || 0,
|
||||
documentElement[scrollHeight] || 0,
|
||||
documentElement[offsetHeight] || 0
|
||||
);
|
||||
return Math.min(
|
||||
100,
|
||||
Math.round((100 * ((documentElement.scrollTop || 0) + documentClientHeight)) / height / 5) * 5
|
||||
);
|
||||
} catch (error) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
addEventListenerFunc("load", function () {
|
||||
scrolled = position();
|
||||
addEventListenerFunc(
|
||||
scroll,
|
||||
function () {
|
||||
if (scrolled < position()) scrolled = position();
|
||||
},
|
||||
false
|
||||
);
|
||||
});
|
||||
/** endif **/
|
||||
|
||||
var getPath = function (overwrite) {
|
||||
var path = overwrite || decodeURIComponentFunc(loc.pathname);
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
// Send page view and append data to it
|
||||
var sendPageView = function (isPushState, deleteSourceInfo, sameSite) {
|
||||
if (isPushState) sendOnLeave("" + lastPageId, true);
|
||||
lastPageId = uuid();
|
||||
page.id = lastPageId;
|
||||
|
||||
var currentPage = locationHostname + getPath();
|
||||
|
||||
sendData(
|
||||
assign(
|
||||
page,
|
||||
deleteSourceInfo
|
||||
? {
|
||||
referrer: sameSite ? referrer : null,
|
||||
}
|
||||
: source,
|
||||
{
|
||||
https: loc.protocol == https,
|
||||
timezone: timezone,
|
||||
type: pageviewsText,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
referrer = currentPage;
|
||||
};
|
||||
|
||||
var pageview = function (isPushState, pathOverwrite) {
|
||||
// Obfuscate personal data in URL by dropping the search and hash
|
||||
var path = getPath(pathOverwrite);
|
||||
|
||||
// Don't send the last path again (this could happen when pushState is used to change the path hash or search)
|
||||
if (lastSendPath == path) return;
|
||||
|
||||
lastSendPath = path;
|
||||
|
||||
var data = {
|
||||
path: path,
|
||||
viewport_width: Math.max(documentElement[clientWidth] || 0, window.innerWidth || 0) || null,
|
||||
viewport_height: Math.max(documentElement[clientHeight] || 0, window.innerHeight || 0) || null,
|
||||
};
|
||||
|
||||
if (nav[language]) data[language] = nav[language];
|
||||
|
||||
if (screen) {
|
||||
data.screen_width = screen.width;
|
||||
data.screen_height = screen.height;
|
||||
}
|
||||
|
||||
// If a user does refresh we need to delete the referrer because otherwise it count double
|
||||
var perf = window.performance; // eslint-disable-line compat/compat
|
||||
var navigation = "navigation";
|
||||
|
||||
// Check if back, forward or reload buttons are being used in modern browsers
|
||||
var userNavigated =
|
||||
perf &&
|
||||
perf.getEntriesByType &&
|
||||
perf.getEntriesByType(navigation)[0] &&
|
||||
perf.getEntriesByType(navigation)[0].type
|
||||
? ["reload", "back_forward"].indexOf(perf.getEntriesByType(navigation)[0].type) > -1
|
||||
: // Check if back, forward or reload buttons are being use in older browsers
|
||||
// 1: TYPE_RELOAD, 2: TYPE_BACK_FORWARD
|
||||
perf && perf[navigation] && [1, 2].indexOf(perf[navigation].type) > -1;
|
||||
|
||||
// Check if referrer is the same as current hostname
|
||||
var sameSite = referrer ? referrer.split(slash)[0] == locationHostname : false;
|
||||
|
||||
/** if uniques **/
|
||||
// We set unique variable based on pushstate or back navigation, if no match we check the referrer
|
||||
data.unique = isPushState || userNavigated ? false : !sameSite;
|
||||
/** endif **/
|
||||
|
||||
page = data;
|
||||
|
||||
sendPageView(isPushState, isPushState || userNavigated, sameSite);
|
||||
};
|
||||
|
||||
pageview();
|
||||
|
||||
/** if events **/
|
||||
var sessionId = uuid();
|
||||
var validTypes = ["string", "number"];
|
||||
|
||||
var sendEvent = function (event, callbackRaw) {
|
||||
var isFunction = event instanceof Function;
|
||||
var callback = callbackRaw instanceof Function ? callbackRaw : function () {};
|
||||
|
||||
if (validTypes.indexOf(typeof event) < 0 && !isFunction) {
|
||||
// warn("event is not a string: " + event);
|
||||
return callback();
|
||||
}
|
||||
|
||||
try {
|
||||
if (isFunction) {
|
||||
event = event();
|
||||
if (validTypes.indexOf(typeof event) < 0) {
|
||||
// warn("event function output is not a string: " + event);
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// warn("in your event function: " + error.message);
|
||||
return callback();
|
||||
}
|
||||
|
||||
event = ("" + event).replace(/[^a-z0-9]+/gi, "_").replace(/(^_|_$)/g, "");
|
||||
|
||||
if (event)
|
||||
sendData(
|
||||
assign(source, bot ? { bot: true } : {}, {
|
||||
type: "event",
|
||||
event: event,
|
||||
page_id: page.id,
|
||||
session_id: sessionId,
|
||||
}),
|
||||
callback
|
||||
);
|
||||
};
|
||||
|
||||
var defaultEventFunc = function (event, callback) {
|
||||
sendEvent(event, callback);
|
||||
};
|
||||
|
||||
// Set default function if user didn't define a function
|
||||
if (!window[options.functionName]) window[options.functionName] = defaultEventFunc;
|
||||
|
||||
var eventFunc = window[options.functionName];
|
||||
|
||||
// Read queue of the user defined function
|
||||
var queue = eventFunc && eventFunc.q ? eventFunc.q : [];
|
||||
|
||||
// Overwrite user defined function
|
||||
window[options.functionName] = defaultEventFunc;
|
||||
|
||||
// Post events from the queue of the user defined function
|
||||
for (var event in queue) sendEvent(queue[event]);
|
||||
/** endif **/
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
})(window, "{{ (urls.Parse .Site.BaseURL).Host }}/api/send_view");
|
@ -198,8 +198,3 @@ disableAliases = true
|
||||
for = "/**"
|
||||
[server.headers.values]
|
||||
Access-Control-Allow-Origin = "*"
|
||||
# TODO: Proxy /api requests to netlify-lambda's local server (port 9337) for each function
|
||||
[[server.redirects]]
|
||||
from = "/api/**"
|
||||
to = "http://localhost:9337/"
|
||||
status = 200
|
||||
|
@ -1,79 +0,0 @@
|
||||
const axios = require("axios");
|
||||
|
||||
exports.handler = function (event, context, callback) {
|
||||
try {
|
||||
// attach a timer to axios to debug response time from endpoint
|
||||
// https://stackoverflow.com/questions/62186171/measure-network-latency-in-react-native/62257712#62257712
|
||||
(function (instance) {
|
||||
instance.interceptors.request.use((request) => {
|
||||
request.startTime = Date.now();
|
||||
return request;
|
||||
});
|
||||
|
||||
instance.interceptors.response.use((response) => {
|
||||
response.elapsedTime = Number((Date.now() - response.config.startTime) / 1000);
|
||||
return response;
|
||||
});
|
||||
})(axios);
|
||||
|
||||
// pass these URL parameters along to endpoint
|
||||
const reqQuery = event.queryStringParameters;
|
||||
reqQuery["ignore-dnt"] = "true"; // this isn't nefarious, we're not tracking in the first place!
|
||||
|
||||
// pass these optional headers along to endpoint
|
||||
const reqHeaders = {
|
||||
referer: event.headers["referer"] || event.headers["Referer"] || "",
|
||||
"user-agent": event.headers["user-agent"] || event.headers["User-Agent"] || "",
|
||||
};
|
||||
|
||||
// if triggered as an image without JS (i.e. from AMP pages) set `?noscript=true`
|
||||
// https://docs.simpleanalytics.com/without-javascript
|
||||
const endpointHost = "queue.simpleanalyticscdn.com";
|
||||
const endpointPath = reqQuery["noscript"] === "true" ? "noscript.gif" : "simple.gif";
|
||||
const endpointUrl = "https://" + endpointHost + "/" + endpointPath;
|
||||
|
||||
axios
|
||||
.request({
|
||||
method: "GET",
|
||||
url: endpointUrl,
|
||||
headers: reqHeaders,
|
||||
params: reqQuery,
|
||||
responseType: "arraybuffer",
|
||||
timeout: 2000,
|
||||
})
|
||||
.then(function (response) {
|
||||
// parse the feedback message from endpoint
|
||||
const apiFeedback = response.headers["simple-analytics-feedback"] || "No feedback from Simple Analytics.";
|
||||
const shortFeedback = apiFeedback.toLowerCase().includes("thanks for sending ")
|
||||
? "OK"
|
||||
: `ERROR: ${apiFeedback}`;
|
||||
|
||||
console.info(`${response.status} ${response.statusText} | ${response.elapsedTime}ms | ${apiFeedback}`);
|
||||
|
||||
// reasoning for base64 encoding:
|
||||
// https://community.netlify.com/t/debugging-a-function-returns-502/429/12
|
||||
callback(null, {
|
||||
statusCode: response.status,
|
||||
headers: {
|
||||
"Content-Type": "image/gif",
|
||||
"Cache-Control": "private, no-cache, no-store, must-revalidate",
|
||||
Expires: "0",
|
||||
Pragma: "no-cache",
|
||||
"x-api-feedback": shortFeedback,
|
||||
"x-api-latency": response.elapsedTime,
|
||||
},
|
||||
body: response.data.toString("base64"),
|
||||
isBase64Encoded: true,
|
||||
});
|
||||
})
|
||||
.catch(function (error) {
|
||||
// this indicates a request error, NOT an error in the endpoint's reponse
|
||||
console.error(error.message);
|
||||
callback(Error(error));
|
||||
});
|
||||
} catch (error) {
|
||||
// something went VERY wrong...
|
||||
console.error(error.message);
|
||||
callback(Error(error));
|
||||
}
|
||||
};
|
13
netlify.toml
13
netlify.toml
@ -1,7 +1,6 @@
|
||||
[build]
|
||||
command = "yarn build"
|
||||
publish = "public"
|
||||
functions = ".netlify/functions"
|
||||
|
||||
[build.environment]
|
||||
NODE_VERSION = "14"
|
||||
@ -25,16 +24,15 @@
|
||||
compress = false
|
||||
|
||||
[context.deploy-preview]
|
||||
command = "yarn build:functions && yarn build:hugo --environment development --baseURL $DEPLOY_PRIME_URL --buildDrafts --buildFuture"
|
||||
command = "yarn build:hugo --environment development --baseURL $DEPLOY_PRIME_URL --buildDrafts --buildFuture"
|
||||
|
||||
[context.branch-deploy]
|
||||
command = "yarn build:functions && yarn build:hugo --environment development --baseURL $DEPLOY_PRIME_URL --buildDrafts --buildFuture"
|
||||
command = "yarn build:hugo --environment development --baseURL $DEPLOY_PRIME_URL --buildDrafts --buildFuture"
|
||||
|
||||
# https://github.com/netlify/cli/blob/master/docs/netlify-dev.md#netlifytoml-dev-block
|
||||
[dev]
|
||||
framework = "#custom"
|
||||
# only start Hugo, `netlify dev` builds/serves functions itself
|
||||
command = "yarn start:hugo --port 1338 --baseURL=/ --appendPort=false --disableLiveReload"
|
||||
command = "yarn start --port 1338 --baseURL=/ --appendPort=false --disableLiveReload"
|
||||
# swap ports to keep consistent w/ normal local server
|
||||
targetPort = 1338
|
||||
port = 1337
|
||||
@ -158,11 +156,6 @@
|
||||
X-XSS-Pwnage = "<script>alert('oops!');</script>"
|
||||
X-View-Source = "https://jrvs.io/src"
|
||||
X-Got-Milk = "2%"
|
||||
## Prettier URLs for Netlify Functions
|
||||
[[redirects]]
|
||||
from = "/api/*"
|
||||
to = "/.netlify/functions/:splat"
|
||||
status = 200
|
||||
|
||||
# More miscellaneous mirrors/redirects:
|
||||
[[redirects]]
|
||||
|
14
package.json
14
package.json
@ -15,12 +15,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rimraf public/ resources/ builds/ _vendor/ .netlify/{cache,functions}/ $TMPDIR/hugo_cache/ || true",
|
||||
"build": "run-s build:hugo build:functions minify",
|
||||
"build": "run-s build:hugo minify",
|
||||
"build:hugo": "hugo --gc --cleanDestinationDir --verbose",
|
||||
"build:functions": "netlify-lambda build functions",
|
||||
"start": "run-p start:hugo start:functions",
|
||||
"start:hugo": "hugo server --disableFastRender --buildDrafts --buildFuture --port=1337 --baseURL=/ --appendPort=false --bind=0.0.0.0 --verbose",
|
||||
"start:functions": "netlify-lambda serve --port 9337 functions",
|
||||
"start": "hugo server --disableFastRender --buildDrafts --buildFuture --port=1337 --baseURL=/ --appendPort=false --bind=0.0.0.0 --verbose",
|
||||
"start:docker": "docker run --rm -v $(pwd):/src:ro -p 1337:1337 $(docker build -q .)",
|
||||
"minify": "run-s minify:**",
|
||||
"minify:html": "html-minifier --html5 --collapse-whitespace --collapse-boolean-attributes --preserve-line-breaks --minify-css --remove-comments --file-ext html --input-dir public --output-dir public **/*.html",
|
||||
@ -37,8 +34,6 @@
|
||||
"@fontsource/comic-neue": "4.2.2",
|
||||
"@fontsource/inter": "4.2.2",
|
||||
"@fontsource/roboto-mono": "4.2.2",
|
||||
"axios": "^0.21.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"normalize.css": "8.0.1",
|
||||
"twemoji": "13.0.2",
|
||||
"twemoji-emojis": "13.0.2"
|
||||
@ -57,16 +52,13 @@
|
||||
"imagemin-cli": "^6.0.0",
|
||||
"lint-staged": "^10.5.4",
|
||||
"markdownlint-cli": "~0.27.1",
|
||||
"netlify-lambda": "^2.0.3",
|
||||
"netlify-plugin-cache": "*",
|
||||
"netlify-plugin-debug-cache": "*",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.x",
|
||||
"postcss-clean": "^1.2.2",
|
||||
"postcss-cli": "^8.3.1",
|
||||
"postcss-color-rgba-fallback": "^4.0.0",
|
||||
"postcss-focus": "^5.0.1",
|
||||
"postcss-import": "^14.0.0",
|
||||
"postcss-import": "^14.0.1",
|
||||
"postcss-reporter": "^7.0.2",
|
||||
"postcss-svgo": "^4.0.2",
|
||||
"prettier": "^2.2.1",
|
||||
|
Loading…
x
Reference in New Issue
Block a user