Skip to content

Configure Renovate #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Local Netlify folder
.netlify
21 changes: 21 additions & 0 deletions generate-token.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export default async (req, context) => {
console.log(123);
try {
const response = await fetch(
"https://app.netlify.com/access-control/generate-access-control-token",
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.NETLIFY_ACCESS_CONTROL_TOKEN}`,
},
}
);
const data = await response.json();
console.log(data);
return new Response(JSON.stringify(data));
} catch (error) {
console.error(error);
return new Response("Error generating token", { status: 500 });
}
};
16 changes: 16 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="main.js" type="module"></script>
</head>
<body>
<h1>Netlify Logs</h1>
<input type="text" id="deployId" placeholder="Deploy ID" />
<input type="text" id="siteId" placeholder="Site ID" />
<button id="connect">Connect</button>
<div id="logs"></div>
</body>
</html>
155 changes: 155 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
let cachedAccessControlToken = null;

async function getAccessControlToken() {
if (cachedAccessControlToken) {
return cachedAccessControlToken;
}

const tokenResp = await fetch(".netlify/functions/generate-token", {
credentials: "include",
});

if (tokenResp.status !== 200) {
cachedAccessControlToken = null;
throw new Error("failed to access control token for user");
}

const { accessControlToken } = await tokenResp.json();

cachedAccessControlToken = accessControlToken;

return accessControlToken;
}

class NetlifyLogsService {
constructor(options = {}) {
this.options = options;
this.logs = [];
this.shouldReconnect = true;
// this.ws = this.connect();
}

destroy() {
this.shouldReconnect = false;
window.clearInterval(this.reconnectTimeout);
this.notifyLogsUpdated.cancel();
this.ws.close();
}

connect(options) {
this.ws = new WebSocket("wss://socketeer.services.netlify.com/build/logs");
this.ws.addEventListener("open", () => {
getAccessControlToken()
.then((accessToken) => {
this.ws.send(
JSON.stringify({
deploy_id: options.deployId || this.options.deployId,
site_id: options.siteId || this.options.siteId,
access_token: accessToken,
})
);
})
.catch((error) => {
console.error(
"NetlifyLogsService failed to get access control token",
error
);
});
});
this.ws.addEventListener("message", (event) => {
try {
const data = JSON.parse(event.data);
const ts = new Date(data.ts).getTime();

if (data.type === "error") {
throw data;
}

this.logs ??= [];
this.logs.push({
id: `${ts}${this.logs.length}`,
timestamp: ts,
message: data.message,
});
this.notifyLogsUpdated();
} catch (e) {
if (e?.type === "error" && e.status === 401) {
console.error("NetlifyLogsService no permission");
this.options.onForbidden?.();
return;
}
console.error(`NetlifyLogsService can't decode socket message`, e);
}
});
this.ws.addEventListener("close", () => {
console.info(`NetlifyLogsService socket closed`);
if (this.shouldReconnect) {
this.reconnectTimeout = window.setTimeout(
() => this.connect(),
this.options.reconnect ?? 1000
);
}
});
this.ws.addEventListener("error", (error) => {
console.error(`NetlifyLogsService socket got error`, error);
this.ws.close();
});
return this.ws;
}

notifyLogsUpdated = (function () {
let timeout;
return function () {
clearTimeout(timeout);
timeout = setTimeout(() => {
this.options.onLogsUpdated?.([...(this.logs ?? [])]);
}, 250);
};
})();
}

const logsService = new NetlifyLogsService({
deployId: "your-deploy-id",
siteId: "your-site-id",
onLogsUpdated: (logs) => {
// Handle updated logs
},
onForbidden: () => {
// Handle forbidden access
},
reconnect: 2000, // Optional reconnect timeout in ms
});

// Initialize the logs service
const netlifyLogs = new NetlifyLogsService({
onLogsUpdated: (logs) => {
// Update UI with new logs
const logContainer = document.querySelector("#logs");
if (logContainer) {
logContainer.innerHTML = logs
.map(
(log) => `
<div class="log-entry">
<span class="timestamp">${new Date(
log.timestamp
).toLocaleTimeString()}</span>
<span class="message">${log.message}</span>
</div>
`
)
.join("");
}
},
onForbidden: () => {
console.error("Access forbidden - please check your credentials");
// Optionally show error message to user
alert("Unable to access logs - permission denied");
},
reconnect: 3000,
});

document.getElementById("connect").addEventListener("click", () => {
const deployId = document.getElementById("deployId").value;
const siteId = document.getElementById("siteId").value;
netlifyLogs.connect({ deployId, siteId });
});
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "netlify-logs",
"version": "1.0.0",
"description": "A simple tool to view Netlify logs",
"main": "index.html",
"scripts": {
"start": "netlify serve"
}
}
6 changes: 6 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"local>netlify/renovate-config"
]
}