dzql 0.5.30 → 0.5.31

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dzql",
3
- "version": "0.5.30",
3
+ "version": "0.5.31",
4
4
  "description": "PostgreSQL-powered framework with zero boilerplate CRUD operations and real-time WebSocket synchronization",
5
5
  "type": "module",
6
6
  "main": "src/server/index.js",
@@ -218,11 +218,40 @@ export class EntityParser {
218
218
  * @private
219
219
  */
220
220
  _parseJSONBuildObject(str) {
221
- // Extract the content between jsonb_build_object( and )
222
- const match = str.match(/jsonb_build_object\s*\(([\s\S]*)\)/i);
223
- if (!match) return {};
221
+ // Find the matching closing parenthesis for jsonb_build_object(
222
+ // Cannot use greedy regex as it matches the LAST ) not the matching one
223
+ const startMatch = str.match(/jsonb_build_object\s*\(/i);
224
+ if (!startMatch) return {};
224
225
 
225
- const content = match[1];
226
+ const startIndex = startMatch.index + startMatch[0].length;
227
+ let depth = 1;
228
+ let inString = false;
229
+ let stringChar = null;
230
+ let endIndex = startIndex;
231
+
232
+ for (let i = startIndex; i < str.length && depth > 0; i++) {
233
+ const char = str[i];
234
+ const prev = i > 0 ? str[i - 1] : '';
235
+
236
+ if ((char === "'" || char === '"') && prev !== '\\') {
237
+ if (!inString) {
238
+ inString = true;
239
+ stringChar = char;
240
+ } else if (char === stringChar) {
241
+ inString = false;
242
+ stringChar = null;
243
+ }
244
+ }
245
+
246
+ if (!inString) {
247
+ if (char === '(') depth++;
248
+ if (char === ')') depth--;
249
+ }
250
+
251
+ endIndex = i;
252
+ }
253
+
254
+ const content = str.substring(startIndex, endIndex);
226
255
  const params = this._parseParameters(content);
227
256
  const result = {};
228
257
 
@@ -260,10 +289,40 @@ export class EntityParser {
260
289
  * @private
261
290
  */
262
291
  _parseJSONBuildArray(str) {
263
- const match = str.match(/jsonb_build_array\s*\(([\s\S]*)\)/i);
264
- if (!match) return [];
292
+ // Find the matching closing parenthesis for jsonb_build_array(
293
+ // Cannot use greedy regex as it matches the LAST ) not the matching one
294
+ const startMatch = str.match(/jsonb_build_array\s*\(/i);
295
+ if (!startMatch) return [];
296
+
297
+ const startIndex = startMatch.index + startMatch[0].length;
298
+ let depth = 1;
299
+ let inString = false;
300
+ let stringChar = null;
301
+ let endIndex = startIndex;
302
+
303
+ for (let i = startIndex; i < str.length && depth > 0; i++) {
304
+ const char = str[i];
305
+ const prev = i > 0 ? str[i - 1] : '';
306
+
307
+ if ((char === "'" || char === '"') && prev !== '\\') {
308
+ if (!inString) {
309
+ inString = true;
310
+ stringChar = char;
311
+ } else if (char === stringChar) {
312
+ inString = false;
313
+ stringChar = null;
314
+ }
315
+ }
316
+
317
+ if (!inString) {
318
+ if (char === '(') depth++;
319
+ if (char === ')') depth--;
320
+ }
321
+
322
+ endIndex = i;
323
+ }
265
324
 
266
- const content = match[1];
325
+ const content = str.substring(startIndex, endIndex);
267
326
  const params = this._parseParameters(content);
268
327
 
269
328
  return params.map(param => {