PageSourceSearch

https://sayapjparea.com/js/global.js?1787301696

js sayapjparea.com collected 2026-10-09 22:45:10 UTC 9,605 bytes, 284 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                    'X-Requested-With': 'XMLHttpRequest',
63                }
64            };
65
66            // Add body for POST, PUT, PATCH requests
67            if (data && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
68                if (useFormData) {
69                    // Use FormData
70                    const formData = new FormData();
71
72                    // Handle different data types
73                    if (data instanceof FormData) {
74                        // If data is already FormData, use it directly
75                        config.body = data;
76                    } else if (typeof data === 'object') {
77                        // Convert object to FormData
78                        Object.keys(data).forEach(key => {
79                            const value = data[key];
80                            if (value instanceof File || value instanceof Blob) {
81                                formData.append(key, value);
82                            } else if (Array.isArray(value)) {
83                                // Handle arrays
84                                value.forEach((item, index) => {
85                                    if (typeof item === 'object' && !(item instanceof File)) {
86                                        formData.append(`${key}[${index}]`, JSON.stringify(item));
87                                    } else {
88                                        formData.append(`${key}[${index}]`, item);
89                                    }
90                                });
91                            } else if (typeof value === 'object' && value !== null) {
92                                formData.append(key, JSON.stringify(value));
93                            } else {
94                                formData.append(key, value);
95                            }
96                        });
97                        config.body = formData;
98                    }
99                    // Don't set Content-Type header for FormData, let browser set it
100                } else {
101                    // Use JSON
102                    config.headers['Content-Type'] = 'application/json';
103                    config.body = JSON.stringify(data);
104                }
105            }
106
107            // Add query parameters for GET requests
108            let finalUrl = BASE_URL + url;
109            if (data && method.toUpperCase() === 'GET') {
110                const queryString = new URLSearchParams(data).toString();
111                finalUrl += queryString ? `?${queryString}` : '';
112            }
113
114            const response = await fetch(finalUrl, config);
115
116            const metaTitle = response.headers.get('X-Title');
117
118            if (metaTitle) {
119                document.title = metaTitle;
120            }
121
122            const metaTags = response.headers.get('X-Meta-Tag');
123
124            if (metaTags && lastMeta != metaTags) {
125                if (metaTags) {
126                    deleteMetaTags()
127                    updateMetaTags(metaTags);
128                } else {
129                    deleteMetaTags()
130                }
131                lastMeta = metaTags;
132            }
133
134            // Check content type before parsing
135            const contentType = response.headers.get('content-type');
136            // console.log(contentType);
137            let responseData = await response.text();
138
139            if (contentType && contentType.includes('application/json')) {
140                responseData = JSON.parse(responseData);
141            }
142
143            if (response.status >= 400) {
144                defaultErrorHandler(responseData);
145                if (onError) {
146                    onError(responseData);
147                }
148            }
149
150            else if (onSuccess) {
151                onSuccess(responseData);
152            }
153
154
155        } catch (error) {
156            // Network or parsing error
157            const errorResponse = {
158                error: {
159                    code: 500,
160                    message: 'Network error atau server tidak merespons'
161                },
162                data: {
163                    success: false
164                },
165                metadata: []
166            };
167
168            if (onError) {
169                onError(errorResponse);
170            } else {
171                defaultErrorHandler(errorResponse);
172            }
173
174            console.error('Network Error:', error);
175            return errorResponse;
176        }
177    };
178
179    // Public API methods
180    return {
181        get: (url, query = null, options = {}) => {
182            return makeRequest('GET', url, query, options);
183        },
184
185        post: (url, body = null, options = {}) => {
186            return makeRequest('POST', url, body, options);
187        },
188
189        put: (url, body = null, options = {}) => {
190            return makeRequest('PUT', url, body, options);
191        },
192
193        patch: (url, body = null, options = {}) => {
194            return makeRequest('PATCH', url, body, options);
195        },
196
197        delete: (url, options = {}) => {
198            return makeRequest('DELETE', url, null, options);
199        },
200
201        // JSON-specific methods (for backward compatibility or when you need JSON)
202        postJson: (url, body = null, options = {}) => {
203            return makeRequest('POST', url, body, { ...options, useFormData: false });
204        },
205
206        putJson: (url, body = null, options = {}) => {
207            return makeRequest('PUT', url, body, { ...options, useFormData: false });
208        },
209
210        patchJson: (url, body = null, options = {}) => {
211            return makeRequest('PATCH', url, body, { ...options, useFormData: false });
212        },
213
214        // Utility methods
215        clearErrors: clearErrorMessages,
216
217        setBaseUrl: (url) => {
218            BASE_URL = url;
219        }
220    };
221})();
222
223// Usage Examples:
224
225// Basic usage with form-data (default)
226// api.post('/change-password', {
227//     password: 'newPassword',
228//     confirmPassword: 'wrongPassword'
229// });
230
231// With file upload
232// const fileInput = document.getElementById('avatar');
233// api.post('/upload-profile', {
234//     name: 'John Doe',
235//     email: '[email protected]',
236//     avatar: fileInput.files[0] // File object
237// });
238
239// With FormData object directly
240// const formData = new FormData();
241// formData.append('username', 'johndoe');
242// formData.append('file', fileInput.files[0]);
243// api.post('/upload', formData);
244
245// Force JSON format (when you need JSON instead of form-data)
246// api.postJson('/api-endpoint', {
247//     data: 'value'
248// });
249
250// Or use options to override
251// api.post('/api-endpoint', {
252//     data: 'value'
253// }, {
254//     useFormData: false // This will use JSON
255// });
256
257// Usage with custom success callback
258// api.post('/change-password', {
259//     password: 'newPassword',
260//     confirmPassword: 'newPassword'
261// }, {
262//     onSuccess: (response) => {
263//         alert('Password berhasil diubah!');
264//         window.location.href = '/dashboard';
265//     }
266// });
267
268// Usage with custom error handling
269// api.get('/users', null, {
270//     onError: (response) => {
271//         console.log('Custom error handling:', response);
272//         // Your custom error logic here
273//     }
274// });
275
276// Usage with custom headers (for authentication)
277// api.post('/protected-endpoint', { data: 'value' }, {
278//     headers: {
279//         'Authorization': 'Bearer ' + localStorage.getItem('token')
280//     },
281//     onSuccess: (response) => {
282//         console.log('Success:', response);
283//     }
284// });

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.