Initial open source release

This commit is contained in:
Ronni Skansing
2025-08-21 16:14:09 +02:00
commit 11cf01f08e
488 changed files with 97180 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
import { API } from '$lib/api/api.js';
import { immediateResponseHandler } from '$lib/api/middleware';
// api singleton where each response is proxyed to the responseHandler
export const api = new Proxy(API.instance, {
get: function(target, prop) {
const apiSection = target[prop];
const apiSectionProxy = new Proxy(apiSection, {
get: function(target, prop) {
const method = new Proxy(target[prop], {
apply: async (target, _, argumentsList) => {
return immediateResponseHandler(await target(...argumentsList));
}
});
return method
}
});
return apiSectionProxy;
}
});
+185
View File
@@ -0,0 +1,185 @@
/**
* Represents the response object returned by the API functions.
* @typedef {Object} ApiResponse
* @property {boolean} success - Indicates whether the request was successful.
* @property {number} statusCode - The status code of the response.
* @property {string} error - The error message, if any.
* @property {any} data - The data returned by the request.
*/
/**
* Fetches JSON data from the specified URL using the GET method.
* @param {string} url - The URL to fetch the JSON data from.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const getJSON = async (url) => {
const res = await fetch(url, {
method: 'GET'
});
const body = await res.json();
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends JSON data to the specified URL using the POST method.
* @param {string} url - The URL to send the JSON data to.
* @param {Object} data - The JSON data to send.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const postJSON = async (url, data) => {
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
let body = {};
try {
body = await res.json();
} catch (e) {
body = {
success: false,
error: 'invalid JSON in response'
};
}
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends JSON data to the specified URL using the POST method.
* @param {string} url - The URL to send the JSON data to.
* @param {Object} data - The JSON data to send.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const patchJSON = async (url, data) => {
const res = await fetch(url, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
let body = {};
try {
body = await res.json();
} catch (e) {
body = {
success: false,
error: 'invalid JSON in response'
};
}
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends JSON data to the specified URL using the PUT method.
* @param {string} url - The URL to send the JSON data to.
* @param {Object} data - The JSON data to send.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const putJSON = async (url, data) => {
const res = await fetch(url, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
let body = {};
try {
body = await res.json();
} catch (e) {
body = {
success: false,
error: 'invalid JSON in response'
};
}
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends JSON data to the specified URL using the DELETE method.
* @param {string} url - The URL to send the JSON data to.
* @param {Object} data - The JSON data to send.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const deleteJSON = async (url, data) => {
const res = await fetch(url, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
let body = {};
try {
body = await res.json();
} catch (e) {
body = {
success: false,
error: 'invalid JSON in response',
data: null
};
}
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends multipart form data to the specified URL using the POST method.
* @param {string} url - The URL to send the multipart data to.
* @param {FormData} formData - The FormData object containing the data to send.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const postMultipart = async (url, formData) => {
console.log(formData);
const res = await fetch(url, {
method: 'POST',
body: formData
});
let body = {};
try {
body = await res.json();
} catch (e) {
body = {
success: false,
error: 'invalid JSON in response'
};
}
return newResponse(body.success, res.status, body.error, body.data);
};
/**
* Sends a DELETE request to the specified URL.
* @param {string} url - The URL to send the DELETE request to.
* @returns {Promise<Object>} - A promise that resolves to the response object containing the JSON data.
*/
export const deleteReq = async (url) => {
// Function implementation
const res = await fetch(url, {
method: 'DELETE'
});
try {
const body = await res.json();
return newResponse(body.success, res.status, body.error, body.data);
} catch (e) {
return newResponse(false, res.status, 'invalid JSON in response', null);
}
};
/**
* Creates a new response object.
* @param {boolean} success - Indicates whether the request was successful.
* @param {number} statusCode - The status code of the response.
* @param {string} error - The error message, if any.
* @param {any} data - The data returned by the request.
* @returns {Object} - The response object.
*/
export function newResponse(success, statusCode, error, data) {
return {
success: success,
statusCode: statusCode,
error: error,
data: data
};
}
+21
View File
@@ -0,0 +1,21 @@
// handle not ok typical responses such as unauthenticated, renew password and such
import { goto } from '$app/navigation';
/**
* @param {import("./client").ApiResponse} apiResponse
* @returns {import("./client").ApiResponse} apiResponse
**/
export const immediateResponseHandler = (apiResponse) => {
// Unauthenticated move the user to the login page
if (apiResponse.statusCode === 401) {
goto('/login');
window.location.reload();
}
// If the user must renew their password, move them to the renew password page
if (apiResponse.statusCode === 400 && apiResponse.error === 'New password required') {
goto('/login/reset-password');
return;
}
return apiResponse;
};