Aditya DN
Upload 6 files
5372a29 verified
import { defaultData, type GitHubData } from '../types';
const address = window.location.origin;
const API_URL = address.replace("3000", "4000") + "/api/data";
// Fungsi untuk decode Base64 yang aman untuk Unicode
function b64DecodeUnicode(str: string) {
try {
return decodeURIComponent(atob(str).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
} catch (e) {
console.error("Gagal mendekode Base64:", e);
// Kembalikan struktur data default jika gagal
return JSON.stringify({ questions: [], message: null });
}
}
// Fungsi untuk encode ke Base64 yang aman untuk Unicode
function b64EncodeUnicode(str: string) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode(parseInt(p1, 16));
}));
}
export const getData = async (): Promise<{ data: GitHubData, sha: string | null }> => {
const response = await fetch(API_URL);
if (response.status === 404) {
// File tidak ada, ini adalah kondisi yang valid untuk repositori baru.
return { data: defaultData, sha: null };
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({ message: response.statusText }));
throw new Error(`Gagal mengambil data dari GitHub: ${errorData.message}`);
}
const responseData = await response.json();
const decodedContent = b64DecodeUnicode(responseData.content || "e30=");
try {
const data = JSON.parse(decodedContent);
// Pastikan data memiliki struktur yang diharapkan
const validatedData: GitHubData = {
idx: data.idx,
direction: data.direction
};
return { data: validatedData, sha: responseData.sha };
} catch(e) {
console.error("Gagal mem-parsing JSON dari GitHub:", e);
throw new Error("Format data dari GitHub tidak valid.");
}
};
export const saveData = async (
data: GitHubData,
commitMessage: string,
sha: string | null
): Promise<{ sha: string }> => {
const content = JSON.stringify(data, null, 2);
const encodedContent = b64EncodeUnicode(content);
console.dir(data, { depth: null, colors: true });
const body: { message: string; content: string; sha?: string } = {
message: commitMessage,
content: encodedContent,
};
if (sha) {
body.sha = sha;
}
let isSuccess = false;
let responseData;
while (!isSuccess) {
try {
const response = await fetch(API_URL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ message: response.statusText }));
throw new Error(`Gagal menyimpan data ke GitHub: ${errorData.message}`);
}
responseData = await response.json();
isSuccess = true;
} catch (e) {
if (e.message.includes("does not match")) {
const newData = await getData();
body.sha = newData.sha;
} else {
isSuccess = true;
}
}
}
return { sha: responseData.content.sha };
};