create-prisma-php-app 1.14.3 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -236,7 +236,7 @@ abstract class Utility
236
236
  case 'endsWith':
237
237
  case 'equals':
238
238
  case 'not':
239
- $validatedValue = Validator::validateString($val);
239
+ $validatedValue = Validator::string($val);
240
240
  $likeOperator = $condition === 'contains' ? ($dbType == 'pgsql' ? 'ILIKE' : 'LIKE') : '=';
241
241
  if ($condition === 'startsWith') $validatedValue .= '%';
242
242
  if ($condition === 'endsWith') $validatedValue = '%' . $validatedValue;
@@ -248,7 +248,7 @@ abstract class Utility
248
248
  case 'gte':
249
249
  case 'lt':
250
250
  case 'lte':
251
- $validatedValue = is_float($val) ? Validator::validateFloat($val) : Validator::validateInt($val);
251
+ $validatedValue = is_float($val) ? Validator::float($val) : Validator::int($val);
252
252
  $operator = $condition === 'gt' ? '>' : ($condition === 'gte' ? '>=' : ($condition === 'lt' ? '<' : '<='));
253
253
  $sqlConditions[] = "$fieldQuoted $operator $bindingKey";
254
254
  $bindings[$bindingKey] = $validatedValue;
@@ -259,7 +259,7 @@ abstract class Utility
259
259
  foreach ($val as $i => $inVal) {
260
260
  $inKey = $bindingKey . "_" . $i;
261
261
  // Assuming the values are strings; adjust validation as necessary.
262
- $validatedValue = Validator::validateString($inVal);
262
+ $validatedValue = Validator::string($inVal);
263
263
  $inPlaceholders[] = $inKey;
264
264
  $bindings[$inKey] = $validatedValue;
265
265
  }
@@ -276,7 +276,7 @@ abstract class Utility
276
276
  // For scalar non-array values; direct equals condition assumed
277
277
  $bindingKey = ":" . $prefix . $key . $level;
278
278
  // Use appropriate validation based on expected type; assuming string for simplicity
279
- $validatedValue = Validator::validateString($value);
279
+ $validatedValue = Validator::string($value);
280
280
  $sqlConditions[] = "$fieldQuoted = $bindingKey";
281
281
  $bindings[$bindingKey] = $validatedValue;
282
282
  }
@@ -4,76 +4,194 @@ namespace Lib;
4
4
 
5
5
  class Validator
6
6
  {
7
- public static function validateString($value)
7
+ // String Validation
8
+
9
+ /**
10
+ * Validate and sanitize a string.
11
+ *
12
+ * @param mixed $value The value to validate.
13
+ * @return string The sanitized string.
14
+ */
15
+ public static function string($value): string
8
16
  {
9
- if ($value === null) {
10
- return '';
11
- }
17
+ return $value !== null ? htmlspecialchars(trim($value), ENT_QUOTES, 'UTF-8') : '';
18
+ }
12
19
 
13
- return htmlspecialchars(trim($value), ENT_QUOTES, 'UTF-8');
20
+ /**
21
+ * Validate an email address.
22
+ *
23
+ * @param mixed $value The value to validate.
24
+ * @return string|null The valid email address or null if invalid.
25
+ */
26
+ public static function email($value): ?string
27
+ {
28
+ return filter_var($value, FILTER_VALIDATE_EMAIL) !== false ? $value : null;
14
29
  }
15
30
 
16
- public static function validateInt($value)
31
+ /**
32
+ * Validate a URL.
33
+ *
34
+ * @param mixed $value The value to validate.
35
+ * @return string|null The valid URL or null if invalid.
36
+ */
37
+ public static function url($value): ?string
17
38
  {
18
- return filter_var($value, FILTER_VALIDATE_INT);
39
+ return filter_var($value, FILTER_VALIDATE_URL) !== false ? $value : null;
19
40
  }
20
41
 
21
- public static function validateFloat($value)
42
+ /**
43
+ * Validate an IP address.
44
+ *
45
+ * @param mixed $value The value to validate.
46
+ * @return string|null The valid IP address or null if invalid.
47
+ */
48
+ public static function ip($value): ?string
22
49
  {
23
- return filter_var($value, FILTER_VALIDATE_FLOAT);
50
+ return filter_var($value, FILTER_VALIDATE_IP) !== false ? $value : null;
24
51
  }
25
52
 
26
- public static function validateBoolean($value)
53
+ /**
54
+ * Validate a UUID.
55
+ *
56
+ * @param mixed $value The value to validate.
57
+ * @return string|null The valid UUID or null if invalid.
58
+ */
59
+ public static function uuid($value): ?string
27
60
  {
28
- return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
61
+ return preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/', $value) ? $value : null;
29
62
  }
30
63
 
31
- public static function validateDate($value)
64
+ /**
65
+ * Validate a size string (e.g., "10MB").
66
+ *
67
+ * @param mixed $value The value to validate.
68
+ * @return string|null The valid size string or null if invalid.
69
+ */
70
+ public static function bytes($value): ?string
32
71
  {
33
- $date = \DateTime::createFromFormat('Y-m-d', $value);
34
- if ($date && $date->format('Y-m-d') === $value) {
35
- return $value;
36
- } else {
37
- return null;
38
- }
72
+ return preg_match('/^[0-9]+[kKmMgGtT]?[bB]?$/', $value) ? $value : null;
39
73
  }
40
74
 
41
- public static function validateDateTime($value)
75
+ /**
76
+ * Validate an XML string.
77
+ *
78
+ * @param mixed $value The value to validate.
79
+ * @return string|null The valid XML string or null if invalid.
80
+ */
81
+ public static function xml($value): ?string
42
82
  {
43
- $date = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
44
- if ($date && $date->format('Y-m-d H:i:s') === $value) {
45
- return $value;
46
- } else {
47
- return null;
48
- }
83
+ return preg_match('/^<\?xml/', $value) ? $value : null;
49
84
  }
50
85
 
51
- public static function validateJson($value)
86
+ // Number Validation
87
+
88
+ /**
89
+ * Validate an integer value.
90
+ *
91
+ * @param mixed $value The value to validate.
92
+ * @return int|null The integer value or null if invalid.
93
+ */
94
+ public static function int($value): ?int
52
95
  {
53
- json_decode($value);
54
- return json_last_error() === JSON_ERROR_NONE;
96
+ return filter_var($value, FILTER_VALIDATE_INT) !== false ? (int)$value : null;
55
97
  }
56
98
 
57
- public static function validateEnum($value, $allowedValues)
99
+ /**
100
+ * Validate a big integer value.
101
+ *
102
+ * @param mixed $value The value to validate.
103
+ * @return int|null The integer value or null if invalid.
104
+ */
105
+ public static function bigInt($value): ?int
58
106
  {
59
- return in_array($value, $allowedValues, true);
107
+ return self::int($value);
108
+ }
109
+
110
+ /**
111
+ * Validate a float value.
112
+ *
113
+ * @param mixed $value The value to validate.
114
+ * @return float|null The float value or null if invalid.
115
+ */
116
+ public static function float($value): ?float
117
+ {
118
+ return filter_var($value, FILTER_VALIDATE_FLOAT) !== false ? (float)$value : null;
119
+ }
120
+
121
+ /**
122
+ * Validate a decimal value.
123
+ *
124
+ * @param mixed $value The value to validate.
125
+ * @return float|null The float value or null if invalid.
126
+ */
127
+ public static function decimal($value): ?float
128
+ {
129
+ return self::float($value);
60
130
  }
61
131
 
62
- public static function validateEmail($value)
132
+ // Date Validation
133
+
134
+ /**
135
+ * Validate a date in a given format.
136
+ *
137
+ * @param mixed $value The value to validate.
138
+ * @param string $format The date format.
139
+ * @return string|null The valid date string or null if invalid.
140
+ */
141
+ public static function date($value, string $format = 'Y-m-d'): ?string
63
142
  {
64
- if ($value === null) {
65
- return '';
66
- }
143
+ $date = \DateTime::createFromFormat($format, $value);
144
+ return $date && $date->format($format) === $value ? $value : null;
145
+ }
67
146
 
68
- return filter_var($value, FILTER_VALIDATE_EMAIL, FILTER_NULL_ON_FAILURE);
147
+ /**
148
+ * Validate a datetime in a given format.
149
+ *
150
+ * @param mixed $value The value to validate.
151
+ * @param string $format The datetime format.
152
+ * @return string|null The valid datetime string or null if invalid.
153
+ */
154
+ public static function dateTime($value, string $format = 'Y-m-d H:i:s'): ?string
155
+ {
156
+ return self::date($value, $format);
157
+ }
158
+
159
+ // Boolean Validation
160
+
161
+ /**
162
+ * Validate a boolean value.
163
+ *
164
+ * @param mixed $value The value to validate.
165
+ * @return bool|null The boolean value or null if invalid.
166
+ */
167
+ public static function boolean($value): ?bool
168
+ {
169
+ return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
69
170
  }
70
171
 
71
- public static function validateUrl($value)
172
+ // Other Validation
173
+
174
+ /**
175
+ * Validate a JSON string.
176
+ *
177
+ * @param mixed $value The value to validate.
178
+ * @return bool True if valid JSON, false otherwise.
179
+ */
180
+ public static function json($value): bool
72
181
  {
73
- if ($value === null) {
74
- return '';
75
- }
182
+ json_decode($value);
183
+ return json_last_error() === JSON_ERROR_NONE;
184
+ }
76
185
 
77
- return filter_var($value, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE);
186
+ /**
187
+ * Validate an enum value against allowed values.
188
+ *
189
+ * @param mixed $value The value to validate.
190
+ * @param array $allowedValues The allowed values.
191
+ * @return bool True if value is allowed, false otherwise.
192
+ */
193
+ public static function enum($value, array $allowedValues): bool
194
+ {
195
+ return in_array($value, $allowedValues, true);
78
196
  }
79
197
  }
@@ -1,342 +1 @@
1
- /**
2
- * Debounces a function to limit the rate at which it is called.
3
- *
4
- * The debounced function will postpone its execution until after the specified wait time
5
- * has elapsed since the last time it was invoked. If `immediate` is `true`, the function
6
- * will be called at the beginning of the wait period instead of at the end.
7
- *
8
- * @param {Function} func - The function to debounce.
9
- * @param {number} [wait=300] - The number of milliseconds to wait before invoking the function.
10
- * @param {boolean} [immediate=false] - If `true`, the function is invoked immediately on the leading edge.
11
- * @returns {Function} - Returns the debounced version of the original function.
12
- */
13
- function debounce(func, wait = 300, immediate = false) {
14
- let timeout;
15
-
16
- return function () {
17
- const context = this;
18
- const args = arguments;
19
- clearTimeout(timeout);
20
-
21
- timeout = setTimeout(() => {
22
- timeout = null;
23
- if (!immediate) func.apply(context, args);
24
- }, wait);
25
-
26
- if (immediate && !timeout) {
27
- func.apply(context, args);
28
- }
29
- };
30
- }
31
-
32
- /**
33
- * Copies text to the clipboard.
34
- *
35
- * @param {string} text - The text to copy.
36
- * @param {HTMLElement} btnElement - The button element that triggered the copy action.
37
- */
38
- function copyToClipboard(text, btnElement) {
39
- navigator.clipboard.writeText(text).then(
40
- function () {
41
- // Clipboard successfully set
42
- const icon = btnElement.querySelector("i");
43
- if (icon) {
44
- icon.className = "fa-regular fa-paste"; // Change to paste icon
45
- }
46
- // Set a timeout to change the icon back to copy after 2000 milliseconds
47
- setTimeout(function () {
48
- if (icon) {
49
- icon.className = "fa-regular fa-copy"; // Change back to copy icon
50
- }
51
- }, 2000); // 2000 milliseconds delay
52
- },
53
- function () {
54
- // Clipboard write failed
55
- alert("Failed to copy command to clipboard");
56
- }
57
- );
58
- }
59
-
60
- /**
61
- * Copies code to the clipboard.
62
- *
63
- * @param {HTMLElement} btnElement - The button element that triggered the copy action.
64
- */
65
- function copyCode(btnElement) {
66
- // Assuming your code block is uniquely identifiable close to your button
67
- const codeBlock = btnElement
68
- .closest(".mockup-code")
69
- .querySelector("pre code");
70
- const textToCopy = codeBlock ? codeBlock.textContent : ""; // Get the text content of the code block
71
-
72
- // Use your existing copyToClipboard function
73
- copyToClipboard(textToCopy, btnElement);
74
- }
75
-
76
- if (
77
- typeof RequestApi === "undefined" &&
78
- typeof StateManager === "undefined"
79
- ) {
80
- /**
81
- * Represents a HTTP request.
82
- */
83
- class RequestApi {
84
- static instance = null;
85
-
86
- /**
87
- * The constructor is now private. To ensure it's not accessible from outside,
88
- * you can throw an error if someone tries to instantiate it directly
89
- * (though JavaScript does not have true private constructors).
90
- */
91
- constructor(baseURL = window.location.origin) {
92
- this.baseURL = baseURL;
93
- }
94
-
95
- /**
96
- * Static method to get instance of RequestApi.
97
- *
98
- * @param {string} [baseURL=window.location.origin] - The base URL for the request.
99
- * @returns {RequestApi} The singleton instance of the RequestApi.
100
- */
101
- static getInstance(baseURL = window.location.origin) {
102
- if (!RequestApi.instance) {
103
- RequestApi.instance = new RequestApi(baseURL);
104
- }
105
- return RequestApi.instance;
106
- }
107
-
108
- /**
109
- * Sends a HTTP request.
110
- *
111
- * @async
112
- * @param {string} method - The HTTP method.
113
- * @param {string} url - The URL to send the request to.
114
- * @param {*} [data=null] - The data to send with the request.
115
- * @param {Object} [headers={}] - The headers to include in the request.
116
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
117
- */
118
- async request(method, url, data = null, headers = {}) {
119
- let fullUrl = `${this.baseURL}${url}`;
120
- const options = {
121
- method,
122
- headers: {
123
- "Content-Type": "application/json",
124
- "X-Requested-With": "XMLHttpRequest",
125
- ...headers,
126
- },
127
- };
128
-
129
- if (data) {
130
- if (method === "GET") {
131
- const params = new URLSearchParams(data).toString();
132
- fullUrl += `?${params}`;
133
- } else if (method !== "HEAD" && method !== "OPTIONS") {
134
- options.body = JSON.stringify(data);
135
- }
136
- }
137
-
138
- try {
139
- const response = await fetch(fullUrl, options);
140
- if (method === "HEAD") {
141
- return response.headers;
142
- }
143
- const contentType = response.headers.get("content-type");
144
- if (contentType && contentType.includes("application/json")) {
145
- return await response.json();
146
- } else {
147
- return await response.text();
148
- }
149
- } catch (error) {
150
- throw error;
151
- }
152
- }
153
-
154
- /**
155
- * Sends a GET request.
156
- *
157
- * @param {string} url - The URL to send the request to.
158
- * @param {*} [params] - The parameters to include in the request.
159
- * @param {Object} [headers={}] - The headers to include in the request.
160
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
161
- */
162
- get(url, params, headers) {
163
- return this.request("GET", url, params, headers);
164
- }
165
-
166
- /**
167
- * Sends a POST request.
168
- *
169
- * @param {string} url - The URL to send the request to.
170
- * @param {*} data - The data to send with the request.
171
- * @param {Object} [headers={}] - The headers to include in the request.
172
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
173
- */
174
- post(url, data, headers) {
175
- return this.request("POST", url, data, headers);
176
- }
177
-
178
- /**
179
- * Sends a PUT request.
180
- *
181
- * @param {string} url - The URL to send the request to.
182
- * @param {*} data - The data to send with the request.
183
- * @param {Object} [headers={}] - The headers to include in the request.
184
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
185
- */
186
- put(url, data, headers) {
187
- return this.request("PUT", url, data, headers);
188
- }
189
-
190
- /**
191
- * Sends a DELETE request.
192
- *
193
- * @param {string} url - The URL to send the request to.
194
- * @param {*} data - The data to send with the request.
195
- * @param {Object} [headers={}] - The headers to include in the request.
196
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
197
- */
198
- delete(url, data, headers) {
199
- return this.request("DELETE", url, data, headers);
200
- }
201
-
202
- /**
203
- * Sends a PATCH request.
204
- *
205
- * @param {string} url - The URL to send the request to.
206
- * @param {*} data - The data to send with the request.
207
- * @param {Object} [headers={}] - The headers to include in the request.
208
- * @returns {Promise<unknown>} - A promise that resolves to the response data.
209
- */
210
- patch(url, data, headers) {
211
- return this.request("PATCH", url, data, headers);
212
- }
213
-
214
- /**
215
- * Sends a HEAD request.
216
- *
217
- * @param {string} url - The URL to send the request to.
218
- * @param {Object} [headers={}] - The headers to include in the request.
219
- * @returns {Promise<unknown>} - A promise that resolves to the response headers.
220
- */
221
- head(url, headers) {
222
- return this.request("HEAD", url, null, headers);
223
- }
224
-
225
- /**
226
- * Sends an OPTIONS request.
227
- *
228
- * @param {string} url - The URL to send the request to.
229
- * @param {Object} [headers={}] - The headers to include in the request.
230
- * @returns {Promise<unknown>} - A promise that resolves to the options available.
231
- */
232
- options(url, headers) {
233
- return this.request("OPTIONS", url, null, headers);
234
- }
235
- }
236
-
237
- /**
238
- * Manages the application state.
239
- */
240
- class StateManager {
241
- static instance = null;
242
-
243
- /**
244
- * Creates a new StateManager instance.
245
- *
246
- * @param {{}} [initialState={}] - The initial state.
247
- */
248
- constructor(initialState = {}) {
249
- this.state = initialState;
250
- this.listeners = [];
251
- }
252
-
253
- /**
254
- * Gets the singleton instance of StateManager.
255
- *
256
- * @static
257
- * @param {{}} [initialState={}] - The initial state.
258
- * @returns {StateManager} - The StateManager instance.
259
- */
260
- static getInstance(initialState = {}) {
261
- if (!StateManager.instance) {
262
- StateManager.instance = new StateManager(initialState);
263
- StateManager.instance.loadState(); // Load state immediately after instance creation
264
- }
265
- return StateManager.instance;
266
- }
267
-
268
- /**
269
- * Sets the state.
270
- *
271
- * @param {*} update - The state update.
272
- * @param {boolean} [saveToStorage=false] - Whether to save the state to localStorage.
273
- */
274
- setState(update, saveToStorage = false) {
275
- this.state = { ...this.state, ...update };
276
- this.listeners.forEach((listener) => listener(this.state));
277
- if (saveToStorage) {
278
- this.saveState();
279
- }
280
- }
281
-
282
- /**
283
- * Subscribes to state changes.
284
- *
285
- * @param {*} listener - The listener function.
286
- * @returns {Function} - A function to unsubscribe the listener.
287
- */
288
- subscribe(listener) {
289
- this.listeners.push(listener);
290
- listener(this.state); // Immediately invoke the listener with the current state
291
- return () =>
292
- (this.listeners = this.listeners.filter((l) => l !== listener));
293
- }
294
-
295
- /**
296
- * Saves the state to localStorage.
297
- */
298
- saveState() {
299
- localStorage.setItem("appState", JSON.stringify(this.state));
300
- }
301
-
302
- /**
303
- * Loads the state from localStorage.
304
- */
305
- loadState() {
306
- const state = localStorage.getItem("appState");
307
- if (state) {
308
- this.state = JSON.parse(state);
309
- this.listeners.forEach((listener) => listener(this.state));
310
- }
311
- }
312
-
313
- /**
314
- * Resets the state to its initial value.
315
- *
316
- * @param {boolean} [clearFromStorage=false] - Whether to clear the state from localStorage.
317
- */
318
- resetState(clearFromStorage = false) {
319
- this.state = {}; // Reset the state to an empty object or a default state if you prefer
320
- this.listeners.forEach((listener) => listener(this.state));
321
- if (clearFromStorage) {
322
- localStorage.removeItem("appState"); // Clear the state from localStorage
323
- }
324
- }
325
- }
326
-
327
- let store = null;
328
- let api = null;
329
-
330
- // Function to initialize instances
331
- function initializeInstances() {
332
- store = StateManager.getInstance();
333
- api = RequestApi.getInstance();
334
- }
335
-
336
- // Initialize instances on initial page load
337
- document.addEventListener("DOMContentLoaded", function () {
338
- initializeInstances();
339
- });
340
- }
341
-
342
- "use strict";var eventAttributes=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"];function attachWireFunctionEvents(){document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((e=>{e instanceof HTMLAnchorElement&&e.addEventListener("click",handleAnchorTag),eventAttributes.forEach((t=>{const n=e.getAttribute(t),o=t.slice(2);n&&(e.removeAttribute(t),e.addEventListener(o,(t=>{t.preventDefault();const{funcName:o,data:r}=parseCallback(e,n);if(o){const e=window[o];if("function"==typeof e)try{e(...r)}catch(e){}else handleUndefinedFunction(o,r)}})))}))}))}async function handleAnchorTag(e){const t=e.currentTarget,n=t.getAttribute("href"),o=t.getAttribute("target");if(!n||"_blank"===o||e.metaKey||e.ctrlKey)return;e.preventDefault();if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else try{history.pushState(null,"",n),window.dispatchEvent(new PopStateEvent("popstate",{state:null}))}catch(e){}}function updateDocumentContent(e){if(e.includes("<!DOCTYPE html>")){const t=(new DOMParser).parseFromString(e,"text/html");document.replaceChild(document.adoptNode(t.documentElement),document.documentElement),attachWireFunctionEvents()}else{const t=document.activeElement,n=t?.id||t?.name,o=t?.value,r=t?.selectionStart,a=t?.selectionEnd,c=(new DOMParser).parseFromString(e,"text/html");if(updateElementContent(document.body,c.body),n){const e=document.getElementById(n)||document.querySelector(`[name="${n}"]`);e instanceof HTMLInputElement&&(e.focus(),"search"===e.type&&(e.value=o||""),null!==r&&null!==a&&e.setSelectionRange(r,a))}attachWireFunctionEvents()}}function updateElementContent(e,t){e.innerHTML!==t.innerHTML&&(e.innerHTML=t.innerHTML),Array.from(t.attributes).forEach((t=>{e.setAttribute(t.name,t.value)}))}function parseCallback(e,t){let n={};if(e instanceof HTMLFormElement){const t=new FormData(e);n=Object.fromEntries(t.entries())}else e instanceof HTMLInputElement&&(e.name?"checkbox"===e.type||"radio"===e.type?n[e.name]=e.checked:n[e.name]=e.value:"checkbox"===e.type||"radio"===e.type?n.value=e.checked:n.value=e.value);const o=t.match(/(\w+)\(([^)]*)\)/);if(o){const e=o[1];let t=[];return o[2]&&(t=o[2].split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((e=>e.trim())),t=t.map((e=>{try{const t=e.replace(/'/g,'"');return JSON.parse(t)}catch{return e}}))),t.forEach((e=>{n="object"==typeof e&&null!==e?{...n,...e}:{...n,args:t}})),{funcName:e,data:n}}return{funcName:t,data:n}}function handleUndefinedFunction(e,t){const n={callback:e,...t},o={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(n)},r={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"}},a=async e=>{const t=await fetch(window.location.pathname,e);return await t.text()};let c="";a(o).then((e=>(""===c&&(c=e),a(r)))).then((e=>{updateDocumentContent(mergeAndReplaceDuplicates(c,e))})).catch((e=>{}))}function mergeAndReplaceDuplicates(e,t){const{html:n,scripts:o}=extractScripts(e),{html:r,scripts:a}=extractScripts(t),c=(new DOMParser).parseFromString(r,"text/html"),i=document.createElement("div");i.innerHTML=n,mergeElementsCompletely(i,c.body);const s=i.innerHTML;return mergeScripts(o,a)+s}function mergeElementsCompletely(e,t){Array.from(e.attributes).forEach((t=>e.removeAttribute(t.name))),Array.from(t.attributes).forEach((t=>e.setAttribute(t.name,t.value))),t.textContent&&!t.children.length&&(e.textContent=t.textContent);const n=Array.from(e.children),o=Array.from(t.children);n.forEach((t=>e.removeChild(t))),o.forEach((t=>e.appendChild(t.cloneNode(!0))))}function extractScripts(e){let t="",n=e;return n=n.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,(e=>(t+=e,""))),{html:n,scripts:t}}function mergeScripts(e,t){const n=new Set([...e.match(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi)||[],...t.match(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi)||[]]);return Array.from(n).join("\n")}document.addEventListener("DOMContentLoaded",(()=>{attachWireFunctionEvents()})),window.addEventListener("popstate",(async()=>{try{const e=await fetch(window.location.href,{headers:{"X-Requested-With":"XMLHttpRequest"}});updateDocumentContent(await e.text())}catch(e){}}));
1
+ "use strict";var eventAttributes=["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onwheel","onkeypress","onkeydown","onkeyup","onfocus","onblur","onchange","oninput","onselect","onsubmit","onreset","onresize","onscroll","onload","onunload","onabort","onerror","onbeforeunload","oncopy","oncut","onpaste","ondrag","ondragstart","ondragend","ondragover","ondragenter","ondragleave","ondrop","oncontextmenu","ontouchstart","ontouchmove","ontouchend","ontouchcancel","onpointerdown","onpointerup","onpointermove","onpointerover","onpointerout","onpointerenter","onpointerleave","onpointercancel"];function attachWireFunctionEvents(){document.querySelectorAll("button, input, select, textarea, a, form, label, div, span").forEach((t=>{t instanceof HTMLAnchorElement&&t.addEventListener("click",handleAnchorTag),eventAttributes.forEach((e=>{const n=t.getAttribute(e),o=e.slice(2);n&&(t.removeAttribute(e),handleDebounce(t,o,n))}))}))}function handleDebounce(t,e,n){const o=t.getAttribute("pp-debounce");if(o){const a=debounce((()=>{invokeHandler(t,n)}),parseInt(o,10));t.addEventListener(e,a)}else t.addEventListener(e,(e=>{e.preventDefault(),invokeHandler(t,n)}))}function invokeHandler(t,e){const{funcName:n,data:o}=parseCallback(t,e);if(n){const t=window[n];if("function"==typeof t)try{t(...o)}catch(t){}else handleUndefinedFunction(n,o)}}async function handleAnchorTag(t){const e=t.currentTarget,n=e.getAttribute("href"),o=e.getAttribute("target");if(!n||"_blank"===o||t.metaKey||t.ctrlKey)return;t.preventDefault();if(/^(https?:)?\/\//i.test(n)&&!n.startsWith(window.location.origin))window.location.href=n;else try{history.pushState(null,"",n),window.dispatchEvent(new PopStateEvent("popstate",{state:null}))}catch(t){}}document.addEventListener("DOMContentLoaded",attachWireFunctionEvents);const state={checkedElements:new Set};function updateDocumentContent(t){if(t.includes("<!DOCTYPE html>")){const e=(new DOMParser).parseFromString(t,"text/html");document.replaceChild(document.adoptNode(e.documentElement),document.documentElement),attachWireFunctionEvents()}else{saveState();const e=saveScrollPositions(),n=(new DOMParser).parseFromString(t,"text/html");updateElementContent(document.body,n.body),restoreState(),restoreScrollPositions(e),attachWireFunctionEvents()}}function saveState(){const t=document.activeElement;state.focusId=t?.id||t?.name,state.focusValue=t?.value,state.focusSelectionStart=t?.selectionStart,state.focusSelectionEnd=t?.selectionEnd,state.checkedElements.clear(),document.querySelectorAll('input[type="checkbox"]:checked').forEach((t=>{state.checkedElements.add(t.id||t.name)}))}function restoreState(){if(state.focusId){const t=document.getElementById(state.focusId)||document.querySelector(`[name="${state.focusId}"]`);t instanceof HTMLInputElement&&(t.focus(),"search"===t.type&&(t.value=state.focusValue||""),void 0!==state.focusSelectionStart&&null!==state.focusSelectionEnd&&t.setSelectionRange(state.focusSelectionStart||null,state.focusSelectionEnd||null))}state.checkedElements.forEach((t=>{const e=document.getElementById(t);e&&(e.checked=!0)}))}function saveScrollPositions(){const t={};return document.querySelectorAll("*").forEach((e=>{(e.scrollTop||e.scrollLeft)&&(t[getElementKey(e)]={scrollTop:e.scrollTop,scrollLeft:e.scrollLeft})})),t}function restoreScrollPositions(t){document.querySelectorAll("*").forEach((e=>{const n=getElementKey(e);t[n]&&(e.scrollTop=t[n].scrollTop,e.scrollLeft=t[n].scrollLeft)}))}function getElementKey(t){return t.id||t.className||t.tagName}function updateElementContent(t,e){t.innerHTML!==e.innerHTML&&(t.innerHTML=e.innerHTML),Array.from(e.attributes).forEach((e=>{t.getAttribute(e.name)!==e.value&&t.setAttribute(e.name,e.value)})),Array.from(t.attributes).forEach((n=>{e.hasAttribute(n.name)||t.removeAttribute(n.name)}))}function parseCallback(t,e){let n={};if(t instanceof HTMLFormElement){const e=new FormData(t);n=Object.fromEntries(e.entries())}else t instanceof HTMLInputElement&&(t.name?"checkbox"===t.type||"radio"===t.type?n[t.name]=t.checked:n[t.name]=t.value:"checkbox"===t.type||"radio"===t.type?n.value=t.checked:n.value=t.value);const o=e.match(/(\w+)\(([^)]*)\)/);if(o){const t=o[1];let e=[];return o[2]&&(e=o[2].split(/,(?=(?:[^'"]*['"][^'"]*['"])*[^'"]*$)/).map((t=>t.trim())),e=e.map((t=>{try{const e=t.replace(/'/g,'"');return JSON.parse(e)}catch{return t}}))),e.forEach((t=>{n="object"==typeof t&&null!==t?{...n,...t}:{...n,args:e}})),{funcName:t,data:n}}return{funcName:e,data:n}}async function handleUndefinedFunction(t,e){const n={callback:t,...e},o={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify(n)},a={method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",HTTP_PPHP_WIRE_REQUEST:"true"},body:JSON.stringify({secondRequest:!0})},s=async t=>{const e=await fetch(window.location.pathname,t);return await e.text()};try{const t=await s(o),e=await s(a);updateDocumentContent(t+e)}catch(t){}}function debounce(t,e=300,n=!1){let o;return function(...a){const s=this;o&&clearTimeout(o),o=setTimeout((()=>{o=null,n||t.apply(s,a)}),e),n&&!o&&t.apply(s,a)}}function copyCode(t,e,n,o,a=2e3){const s=t.closest(`.${e}`)?.querySelector("pre code"),c=s?.textContent?.trim()||"";c?navigator.clipboard.writeText(c).then((()=>{const e=t.querySelector("i");e&&(e.className=o),setTimeout((()=>{e&&(e.className=n)}),a)}),(()=>{alert("Failed to copy command to clipboard")})):alert("Failed to find the code block to copy")}window.addEventListener("popstate",(async()=>{try{const t=await fetch(window.location.href,{headers:{"X-Requested-With":"XMLHttpRequest"}});updateDocumentContent(await t.text())}catch(t){}}));let api=null;if(void 0===api){class t{static instance=null;baseURL;constructor(t=window.location.origin){this.baseURL=t}static getInstance(e=window.location.origin){return t.instance||(t.instance=new t(e)),t.instance}async request(t,e,n=null,o={}){let a=`${this.baseURL}${e}`;const s={method:t,headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",...o}};if(n)if("GET"===t){a+=`?${new URLSearchParams(n).toString()}`}else"HEAD"!==t&&"OPTIONS"!==t&&(s.body=JSON.stringify(n));try{const e=await fetch(a,s);if("HEAD"===t)return e.headers;const n=e.headers.get("content-type");return n&&n.includes("application/json")?await e.json():await e.text()}catch(t){throw t}}get(t,e,n){return this.request("GET",t,e,n)}post(t,e,n){return this.request("POST",t,e,n)}put(t,e,n){return this.request("PUT",t,e,n)}delete(t,e,n){return this.request("DELETE",t,e,n)}patch(t,e,n){return this.request("PATCH",t,e,n)}head(t,e){return this.request("HEAD",t,null,e)}options(t,e){return this.request("OPTIONS",t,null,e)}}api=t.getInstance()}let store=null;if(void 0===store){class t{static instance=null;state;listeners;constructor(t={}){this.state=t,this.listeners=[]}static getInstance(e={}){return t.instance||(t.instance=new t(e),t.instance.loadState()),t.instance}setState(t,e=!1){this.state={...this.state,...t},this.listeners.forEach((t=>t(this.state))),e&&this.saveState()}subscribe(t){return this.listeners.push(t),t(this.state),()=>{this.listeners=this.listeners.filter((e=>e!==t))}}saveState(){localStorage.setItem("appState",JSON.stringify(this.state))}loadState(){const t=localStorage.getItem("appState");t&&(this.state=JSON.parse(t),this.listeners.forEach((t=>t(this.state))))}resetState(t=!1){this.state={},this.listeners.forEach((t=>t(this.state))),t&&localStorage.removeItem("appState")}}store=t.getInstance()}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-prisma-php-app",
3
- "version": "1.14.3",
3
+ "version": "1.15.0",
4
4
  "description": "Prisma-PHP: A Revolutionary Library Bridging PHP with Prisma ORM",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",