PageSourceSearch

https://jkt4dslot.com/js/global.js?1771218210

js jkt4dslot.com collected 2026-09-27 12:14:26 UTC 9,535 bytes, 283 lines download raw bytes

1var lastMeta = "";
2
3// Global API utility functions
4window.api = (() => {
5    const BASE_URL = ''; // Set your base URL here if needed
6
7    // Default error handler that looks for error spans
8    const defaultErrorHandler = (response) => {
9        // Clear all existing error messages first
10        clearErrorMessages();
11        if (response.metadata && response.metadata.validation) {
12            // Handle validation errors
13            Object.keys(response.metadata.validation).forEach(field => {
14                const errorSpan = document.getElementById(`error-${field}`);
15                console.log(errorSpan);
16                if (errorSpan && response.metadata.validation[field].length > 0) {
17                    errorSpan.textContent = response.metadata.validation[field][0];
18                }
19            });
20        } else if (response.error && response.error.message) {
21            // Handle general error message
22            console.error('API Error:', response.error.message);
23
24            // Look for a general error container
25            const generalErrorSpan = document.getElementById('error-general') ||
26                document.getElementById('error-message');
27            if (generalErrorSpan) {
28                generalErrorSpan.textContent = response.error.message;
29            }
30        }
31    };
32
33    // Function to clear all error messages
34    const clearErrorMessages = () => {
35        const errorSpans = document.querySelectorAll('[id^="error-"]');
36        errorSpans.forEach(span => {
37            span.textContent = '';
38        });
39    };
40
41    // Main request function
42    const makeRequest = async (method, url, data = null, options = {}) => {
43        const {
44            onSuccess = null,
45            onError = null,
46            headers = {},
47            clearErrors = true,
48            useFormData = true // Default to form-data
49        } = options;
50
51        // Clear existing errors if requested
52        if (clearErrors) {
53            clearErrorMessages();
54        }
55
56        try {
57            const config = {
58                method: method.toUpperCase(),
59                headers: {
60                    ...headers,
61                    'Accept': 'application/json',
62                }
63            };
64
65            // Add body for POST, PUT, PATCH requests
66            if (data && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
67                if (useFormData) {
68                    // Use FormData
69                    const formData = new FormData();
70
71                    // Handle different data types
72                    if (data instanceof FormData) {
73                        // If data is already FormData, use it directly
74                        config.body = data;
75                    } else if (typeof data === 'object') {
76                        // Convert object to FormData
77                        Object.keys(data).forEach(key => {
78                            const value = data[key];
79                            if (value instanceof File || value instanceof Blob) {
80                                formData.append(key, value);
81                            } else if (Array.isArray(value)) {
82                                // Handle arrays
83                                value.forEach((item, index) => {
84                                    if (typeof item === 'object' && !(item instanceof File)) {
85                                        formData.append(`${key}[${index}]`, JSON.stringify(item));
86                                    } else {
87                                        formData.append(`${key}[${index}]`, item);
88                                    }
89                                });
90                            } else if (typeof value === 'object' && value !== null) {
91                                formData.append(key, JSON.stringify(value));
92                            } else {
93                                formData.append(key, value);
94                            }
95                        });
96                        config.body = formData;
97                    }
98                    // Don't set Content-Type header for FormData, let browser set it
99                } else {
100                    // Use JSON
101                    config.headers['Content-Type'] = 'application/json';
102                    config.body = JSON.stringify(data);
103                }
104            }
105
106            // Add query parameters for GET requests
107            let finalUrl = BASE_URL + url;
108            if (data && method.toUpperCase() === 'GET') {
109                const queryString = new URLSearchParams(data).toString();
110                finalUrl += queryString ? `?${queryString}` : '';
111            }
112
113            const response = await fetch(finalUrl, config);
114
115            const metaTitle = response.headers.get('X-Title');
116
117            if (metaTitle) {
118                document.title = metaTitle;
119            }
120
121            const metaTags = response.headers.get('X-Meta-Tag');
122
123            if (lastMeta != metaTags) {
124                if (metaTags) {
125                    deleteMetaTags()
126                    updateMetaTags(metaTags);
127                } else {
128                    deleteMetaTags()
129                }
130                lastMeta = metaTags;
131            }
132
133            // Check content type before parsing
134            const contentType = response.headers.get('content-type');
135            // console.log(contentType);
136            let responseData = await response.text();
137
138            if (contentType && contentType.includes('application/json')) {
139                responseData = JSON.parse(responseData);
140            }
141
142            if (response.status >= 400) {
143                defaultErrorHandler(responseData);
144                if (onError) {
145                    onError(responseData);
146                }
147            }
148
149            else if (onSuccess) {
150                onSuccess(responseData);
151            }
152
153
154        } catch (error) {
155            // Network or parsing error
156            const errorResponse = {
157                error: {
158                    code: 500,
159                    message: 'Network error atau server tidak merespons'
160                },
161                data: {
162                    success: false
163                },
164                metadata: []
165            };
166
167            if (onError) {
168                onError(errorResponse);
169            } else {
170                defaultErrorHandler(errorResponse);
171            }
172
173            console.error('Network Error:', error);
174            return errorResponse;
175        }
176    };
177
178    // Public API methods
179    return {
180        get: (url, query = null, options = {}) => {
181            return makeRequest('GET', url, query, options);
182        },
183
184        post: (url, body = null, options = {}) => {
185            return makeRequest('POST', url, body, options);
186        },
187
188        put: (url, body = null, options = {}) => {
189            return makeRequest('PUT', url, body, options);
190        },
191
192        patch: (url, body = null, options = {}) => {
193            return makeRequest('PATCH', url, body, options);
194        },
195
196        delete: (url, options = {}) => {
197            return makeRequest('DELETE', url, null, options);
198        },
199
200        // JSON-specific methods (for backward compatibility or when you need JSON)
201        postJson: (url, body = null, options = {}) => {
202            return makeRequest('POST', url, body, { ...options, useFormData: false });
203        },
204
205        putJson: (url, body = null, options = {}) => {
206            return makeRequest('PUT', url, body, { ...options, useFormData: false });
207        },
208
209        patchJson: (url, body = null, options = {}) => {
210            return makeRequest('PATCH', url, body, { ...options, useFormData: false });
211        },
212
213        // Utility methods
214        clearErrors: clearErrorMessages,
215
216        setBaseUrl: (url) => {
217            BASE_URL = url;
218        }
219    };
220})();
221
222// Usage Examples:
223
224// Basic usage with form-data (default)
225// api.post('/change-password', {
226//     password: 'newPassword',
227//     confirmPassword: 'wrongPassword'
228// });
229
230// With file upload
231// const fileInput = document.getElementById('avatar');
232// api.post('/upload-profile', {
233//     name: 'John Doe',
234//     email: '[email protected]',
235//     avatar: fileInput.files[0] // File object
236// });
237
238// With FormData object directly
239// const formData = new FormData();
240// formData.append('username', 'johndoe');
241// formData.append('file', fileInput.files[0]);
242// api.post('/upload', formData);
243
244// Force JSON format (when you need JSON instead of form-data)
245// api.postJson('/api-endpoint', {
246//     data: 'value'
247// });
248
249// Or use options to override
250// api.post('/api-endpoint', {
251//     data: 'value'
252// }, {
253//     useFormData: false // This will use JSON
254// });
255
256// Usage with custom success callback
257// api.post('/change-password', {
258//     password: 'newPassword',
259//     confirmPassword: 'newPassword'
260// }, {
261//     onSuccess: (response) => {
262//         alert('Password berhasil diubah!');
263//         window.location.href = '/dashboard';
264//     }
265// });
266
267// Usage with custom error handling
268// api.get('/users', null, {
269//     onError: (response) => {
270//         console.log('Custom error handling:', response);
271//         // Your custom error logic here
272//     }
273// });
274
275// Usage with custom headers (for authentication)
276// api.post('/protected-endpoint', { data: 'value' }, {
277//     headers: {
278//         'Authorization': 'Bearer ' + localStorage.getItem('token')
279//     },
280//     onSuccess: (response) => {
281//         console.log('Success:', response);
282//     }
283// });

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.