feat(api): added an incident search api

CHANGE: feature request in https://github.com/rajnandan1/kener/issues/64
This commit is contained in:
Raj Nandan Sharma
2024-04-12 09:38:41 +05:30
parent dbc76a9106
commit 94877a056a
4 changed files with 126 additions and 4 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "kener",
"version": "0.0.5",
"version": "0.0.10",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "kener",
"version": "0.0.5",
"version": "0.0.10",
"license": "MIT",
"dependencies": {
"axios": "^1.6.2",

View File

@@ -1,6 +1,6 @@
{
"name": "kener",
"version": "0.0.10",
"version": "0.0.11",
"private": false,
"license": "MIT",
"description": "Kener: An open-source Node.js status page application for real-time service monitoring, incident management, and customizable reporting. Simplify service outage tracking, enhance incident communication, and ensure a seamless user experience.",

View File

@@ -341,6 +341,44 @@ async function UpdateIssueLabels(githubConfig, incidentNumber, issueLabels, body
}
}
//search issue
async function SearchIssue(query, page, per_page) {
if (GH_TOKEN === undefined) {
console.log(GhnotconfireguredMsg);
return null;
}
const searchQuery =
query
.filter(function (q) {
if (q == "" || q === undefined || q === null) {
return false;
}
const qs = q.split(":");
if (qs.length < 2) {
return false;
}
if (qs[1] === "" || qs[1] === undefined || qs[1] === null) {
return false;
}
return true;
})
.join(" ")
const url = `https://api.github.com/search/issues?q=${encodeURIComponent(
searchQuery
)}&per_page=${per_page}&page=${page}`;
try {
const response = await axios.request(getAxiosOptions(url));
return response.data;
} catch (error) {
console.log(error.response.data);
return null;
}
}
export {
GetAllGHLabels,
CreateGHLabel,
@@ -357,4 +395,5 @@ export {
CloseIssue,
GetOpenIncidents,
FilterAndInsertMonitorInIncident,
SearchIssue,
};

View File

@@ -2,7 +2,7 @@
// @ts-ignore
import { json } from "@sveltejs/kit";
import { ParseIncidentPayload, auth, GHIssueToKenerIncident } from "$lib/server/webhook";
import { CreateIssue } from "../../../../scripts/github";
import { CreateIssue, SearchIssue } from "../../../../scripts/github";
import { env } from "$env/dynamic/public";
import fs from "fs-extra";
@@ -43,4 +43,87 @@ export async function POST({ request }) {
return json(GHIssueToKenerIncident(resp), {
status: 200,
});
}
export async function GET({ request, url }) {
const authError = auth(request);
if (authError !== null) {
return json(
{ error: authError.message },
{
status: 401,
}
);
}
const query = url.searchParams;
const state = query.get("state") || "open";
const tags = query.get("tags") || ""; //comma separated list of tags
const page = query.get("page") || 1;
const per_page = query.get("per_page") || 10;
const createdAfter = query.get("created_after_utc") || "";
const createdBefore = query.get("created_before_utc") || "";
const titleLike = query.get("title_like") || "";
//if state is not open or closed, return 400
if (state !== "open" && state !== "closed") {
return json(
{ error: "state must be open or closed" },
{
status: 400,
}
);
}
let site = JSON.parse(
fs.readFileSync(env.PUBLIC_KENER_FOLDER + "/site.json", "utf8")
);
let github = site.github;
const repo = `${github.owner}/${github.repo}`;
const is = "issue";
const filterArray = [
`repo:${repo}`,
`is:${is}`,
`state:${state}`,
`label:incident`,
`sort:created-desc`,
`label:${tags.split(",").map((tag) => tag.trim()).join(",")}`
];
//if createdAfter and createdBefore are both set, use the range filter
if (createdBefore && createdAfter) {
let dateFilter = "";
let iso = new Date(createdAfter * 1000).toISOString();
dateFilter += `created:${iso}`;
iso = new Date(createdBefore * 1000).toISOString();
dateFilter += `..${iso}`;
filterArray.push(dateFilter);
} else if(createdAfter){ //if only createdAfter is set, use the greater than or equal to filter
let iso = new Date(createdAfter * 1000).toISOString();
filterArray.push(`created:>=${iso}`);
} else if(createdBefore){//if only createdBefore is set, use the less than or equal to filter
let iso = new Date(createdBefore * 1000).toISOString();
filterArray.push(`created:<=${iso}`);
}
if(titleLike){
filterArray.unshift(`${titleLike} in:title`);
}
const resp = await SearchIssue(filterArray, page, per_page);
const incidents = resp.items.map((issue) => GHIssueToKenerIncident(issue));
return json(
incidents,
{
status: 200,
}
);
}