| | import { defaultData, type GitHubData } from '../types';
|
| |
|
| | const address = window.location.origin;
|
| | const API_URL = address.replace("3000", "4000") + "/api/data";
|
| |
|
| |
|
| | 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);
|
| |
|
| | return JSON.stringify({ questions: [], message: null });
|
| | }
|
| | }
|
| |
|
| |
|
| | 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) {
|
| |
|
| | 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);
|
| |
|
| | 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 };
|
| | };
|
| |
|