@bungres/kit 0.1.1 → 0.4.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.
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ async function loadConfig(cwd = process.cwd()) {
38
38
  // src/schema-loader.ts
39
39
  import { resolve as resolve2, join as join2 } from "path";
40
40
 
41
- // ../bungres-orm/src/table.ts
41
+ // ../bungres-orm/src/schema/table.ts
42
42
  var TableConfigSymbol = Symbol.for("BungresTableConfig");
43
43
  function getTableConfig(table) {
44
44
  return table[TableConfigSymbol];
@@ -48,8 +48,13 @@ function camelToSnakeCase(str) {
48
48
  }
49
49
  function createTableFactory(casing) {
50
50
  return function(name, columns, extra) {
51
+ let schema;
52
+ if (extra && typeof extra !== "function") {
53
+ schema = extra.schema;
54
+ }
55
+ const qualifiedName = schema ? `"${schema}"."${name}"` : `"${name}"`;
51
56
  const columnConfigs = Object.fromEntries(Object.entries(columns).map(([key, config]) => {
52
- const c = { ...config };
57
+ const c = { ...config, tableName: qualifiedName };
53
58
  if (!c.name) {
54
59
  if (casing === "snake") {
55
60
  c.name = camelToSnakeCase(key);
@@ -59,16 +64,40 @@ function createTableFactory(casing) {
59
64
  }
60
65
  return [key, c];
61
66
  }));
62
- const schema = extra?.schema;
63
- const qualifiedName = schema ? `"${schema}"."${name}"` : `"${name}"`;
67
+ const indexes = [];
68
+ const checks = [];
69
+ const primaryKeys = [];
70
+ const foreignKeys = [];
71
+ if (extra) {
72
+ if (typeof extra === "function") {
73
+ const builders = extra(columnConfigs);
74
+ for (const builder of builders) {
75
+ const config = builder.build();
76
+ if (config.type === "index")
77
+ indexes.push(config);
78
+ else if (config.type === "check")
79
+ checks.push(config.condition);
80
+ else if (config.type === "primaryKey")
81
+ primaryKeys.push(...config.columns);
82
+ else if (config.type === "foreignKey")
83
+ foreignKeys.push(config);
84
+ }
85
+ } else {
86
+ if (extra.indexes)
87
+ indexes.push(...extra.indexes);
88
+ if (extra.checks)
89
+ checks.push(...extra.checks);
90
+ }
91
+ }
64
92
  const tableObj = {
65
93
  [TableConfigSymbol]: {
66
94
  name,
67
95
  schema,
68
96
  columns: columnConfigs,
69
- indexes: extra?.indexes ?? [],
70
- checks: extra?.checks ?? [],
71
- primaryKeys: extra?.primaryKeys ?? [],
97
+ indexes,
98
+ checks,
99
+ primaryKeys,
100
+ foreignKeys,
72
101
  qualifiedName
73
102
  }
74
103
  };
@@ -78,7 +107,7 @@ function createTableFactory(casing) {
78
107
  var table = createTableFactory("none");
79
108
  var snakeCase = { table: createTableFactory("snake") };
80
109
  var camelCase = { table: createTableFactory("camel") };
81
- // ../bungres-orm/src/column.ts
110
+ // ../bungres-orm/src/schema/columns.ts
82
111
  function buildColumn(dataType, nameOrOpts, opts) {
83
112
  let name = "";
84
113
  let options = opts;
@@ -132,7 +161,33 @@ var interval = col("interval");
132
161
  var inet = col("inet");
133
162
  var cidr = col("cidr");
134
163
  var macaddr = col("macaddr");
135
- // ../bungres-orm/src/sql.ts
164
+ var textArray = col("text[]");
165
+ var integerArray = col("integer[]");
166
+ var varcharArray = col("varchar[]");
167
+ var uuidArray = col("uuid[]");
168
+ // ../bungres-orm/src/core/sql.ts
169
+ function sql(strings, ...values) {
170
+ let query = "";
171
+ const params = [];
172
+ for (let i = 0;i < strings.length; i++) {
173
+ query += strings[i];
174
+ if (i < values.length) {
175
+ const val = values[i];
176
+ if (isSQLChunk(val)) {
177
+ const offset = params.length;
178
+ query += val.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
179
+ params.push(...val.params);
180
+ } else {
181
+ params.push(val);
182
+ query += `$${params.length}`;
183
+ }
184
+ }
185
+ }
186
+ return { sql: query, params };
187
+ }
188
+ function isSQLChunk(value) {
189
+ return typeof value === "object" && value !== null && "sql" in value && "params" in value && typeof value.sql === "string" && Array.isArray(value.params);
190
+ }
136
191
  function sqlJoin(chunks, separator = ", ") {
137
192
  const params = [];
138
193
  const parts = [];
@@ -143,12 +198,326 @@ function sqlJoin(chunks, separator = ", ") {
143
198
  }
144
199
  return { sql: parts.join(separator), params };
145
200
  }
146
- // ../bungres-orm/src/query.ts
201
+ function rawSql(query) {
202
+ return { sql: query, params: [] };
203
+ }
204
+ // ../bungres-orm/src/core/conditions.ts
205
+ var colName = (c) => {
206
+ if (typeof c === "string")
207
+ return `"${c}"`;
208
+ if (isSQLChunk(c))
209
+ return c.sql;
210
+ return c.tableName ? `${c.tableName}."${c.name}"` : `"${c.name}"`;
211
+ };
212
+ function isColumnConfig(val) {
213
+ return val !== null && typeof val === "object" && "name" in val && "dataType" in val;
214
+ }
215
+ var eq = (column, value) => {
216
+ if (isColumnConfig(value))
217
+ return sql`${rawSql(colName(column))} = ${rawSql(colName(value))}`;
218
+ if (isSQLChunk(value))
219
+ return sql`${rawSql(colName(column))} = ${value}`;
220
+ return sql`${rawSql(colName(column))} = ${value}`;
221
+ };
222
+ var ne = (column, value) => {
223
+ if (isColumnConfig(value))
224
+ return sql`${rawSql(colName(column))} != ${rawSql(colName(value))}`;
225
+ if (isSQLChunk(value))
226
+ return sql`${rawSql(colName(column))} != ${value}`;
227
+ return sql`${rawSql(colName(column))} != ${value}`;
228
+ };
229
+ var gt = (column, value) => {
230
+ if (isColumnConfig(value))
231
+ return sql`${rawSql(colName(column))} > ${rawSql(colName(value))}`;
232
+ if (isSQLChunk(value))
233
+ return sql`${rawSql(colName(column))} > ${value}`;
234
+ return sql`${rawSql(colName(column))} > ${value}`;
235
+ };
236
+ var gte = (column, value) => {
237
+ if (isColumnConfig(value))
238
+ return sql`${rawSql(colName(column))} >= ${rawSql(colName(value))}`;
239
+ if (isSQLChunk(value))
240
+ return sql`${rawSql(colName(column))} >= ${value}`;
241
+ return sql`${rawSql(colName(column))} >= ${value}`;
242
+ };
243
+ var lt = (column, value) => {
244
+ if (isColumnConfig(value))
245
+ return sql`${rawSql(colName(column))} < ${rawSql(colName(value))}`;
246
+ if (isSQLChunk(value))
247
+ return sql`${rawSql(colName(column))} < ${value}`;
248
+ return sql`${rawSql(colName(column))} < ${value}`;
249
+ };
250
+ var lte = (column, value) => {
251
+ if (isColumnConfig(value))
252
+ return sql`${rawSql(colName(column))} <= ${rawSql(colName(value))}`;
253
+ if (isSQLChunk(value))
254
+ return sql`${rawSql(colName(column))} <= ${value}`;
255
+ return sql`${rawSql(colName(column))} <= ${value}`;
256
+ };
257
+ var like = (column, pattern) => sql`${rawSql(colName(column))} LIKE ${pattern}`;
258
+ var ilike = (column, pattern) => sql`${rawSql(colName(column))} ILIKE ${pattern}`;
259
+ var isNull = (column) => rawSql(`${colName(column)} IS NULL`);
260
+ var isNotNull = (column) => rawSql(`${colName(column)} IS NOT NULL`);
261
+ var inArray = (column, values) => {
262
+ if (values.length === 0)
263
+ return rawSql("FALSE");
264
+ const params = values;
265
+ const placeholders = params.map((_, i) => `$${i + 1}`).join(", ");
266
+ return { sql: `${colName(column)} = ANY(ARRAY[${placeholders}])`, params };
267
+ };
268
+ var and = (...conditions) => sqlJoin(conditions, " AND ");
269
+ var or = (...conditions) => {
270
+ const joined = sqlJoin(conditions, " OR ");
271
+ return { sql: `(${joined.sql})`, params: joined.params };
272
+ };
273
+ var not = (condition) => ({
274
+ sql: `NOT (${condition.sql})`,
275
+ params: condition.params
276
+ });
277
+ var asc = (column) => sql`${rawSql(colName(column))} ASC`;
278
+ var desc = (column) => sql`${rawSql(colName(column))} DESC`;
279
+ function parseWhereObject(tableConfig, whereObj) {
280
+ const conditions = [];
281
+ for (const [key, val] of Object.entries(whereObj)) {
282
+ if (val === undefined)
283
+ continue;
284
+ if (key === "OR") {
285
+ const orConditions = val.map((o) => parseWhereObject(tableConfig, o));
286
+ if (orConditions.length > 0)
287
+ conditions.push(or(...orConditions));
288
+ continue;
289
+ }
290
+ if (key === "AND") {
291
+ const andConditions = val.map((o) => parseWhereObject(tableConfig, o));
292
+ if (andConditions.length > 0)
293
+ conditions.push(and(...andConditions));
294
+ continue;
295
+ }
296
+ if (key === "NOT") {
297
+ conditions.push(not(parseWhereObject(tableConfig, val)));
298
+ continue;
299
+ }
300
+ const colConfig = tableConfig.columns[key];
301
+ const columnArg = colConfig ?? key;
302
+ if (val !== null && typeof val === "object" && !Array.isArray(val) && !(val instanceof Date) && !(val instanceof Uint8Array)) {
303
+ const opVal = val;
304
+ if (opVal.eq !== undefined)
305
+ conditions.push(eq(columnArg, opVal.eq));
306
+ if (opVal.ne !== undefined)
307
+ conditions.push(ne(columnArg, opVal.ne));
308
+ if (opVal.gt !== undefined)
309
+ conditions.push(gt(columnArg, opVal.gt));
310
+ if (opVal.gte !== undefined)
311
+ conditions.push(gte(columnArg, opVal.gte));
312
+ if (opVal.lt !== undefined)
313
+ conditions.push(lt(columnArg, opVal.lt));
314
+ if (opVal.lte !== undefined)
315
+ conditions.push(lte(columnArg, opVal.lte));
316
+ if (opVal.in !== undefined)
317
+ conditions.push(inArray(columnArg, opVal.in));
318
+ if (opVal.like !== undefined)
319
+ conditions.push(like(columnArg, opVal.like));
320
+ if (opVal.ilike !== undefined)
321
+ conditions.push(ilike(columnArg, opVal.ilike));
322
+ if (opVal.isNull)
323
+ conditions.push(isNull(columnArg));
324
+ if (opVal.isNotNull)
325
+ conditions.push(isNotNull(columnArg));
326
+ } else {
327
+ if (val === null) {
328
+ conditions.push(isNull(columnArg));
329
+ } else {
330
+ conditions.push(eq(columnArg, val));
331
+ }
332
+ }
333
+ }
334
+ if (conditions.length === 0) {
335
+ return rawSql("TRUE");
336
+ }
337
+ return and(...conditions);
338
+ }
339
+ function parseOrderByObject(tableConfig, orderByObj) {
340
+ const parts = [];
341
+ for (const [key, dir] of Object.entries(orderByObj)) {
342
+ if (dir === undefined)
343
+ continue;
344
+ const colConfig = tableConfig.columns[key];
345
+ const columnArg = colConfig ?? key;
346
+ if (dir === "asc")
347
+ parts.push(asc(columnArg));
348
+ else if (dir === "desc")
349
+ parts.push(desc(columnArg));
350
+ }
351
+ return parts;
352
+ }
353
+
354
+ // ../bungres-orm/src/builders/delete.ts
355
+ class DeleteBuilder {
356
+ _table;
357
+ _executor;
358
+ _where = [];
359
+ _returning;
360
+ _comment;
361
+ constructor(table2, executor) {
362
+ this._table = table2;
363
+ this._executor = executor;
364
+ }
365
+ then(onfulfilled, onrejected) {
366
+ return this._executor.execute(this).then(onfulfilled, onrejected);
367
+ }
368
+ async single() {
369
+ return this._executor.executeSingle(this);
370
+ }
371
+ where(condition) {
372
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
373
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
374
+ } else {
375
+ this._where.push(condition);
376
+ }
377
+ return this;
378
+ }
379
+ returning(...columns) {
380
+ this._returning = columns.length > 0 ? columns : ["*"];
381
+ return this;
382
+ }
383
+ comment(tag) {
384
+ this._comment = tag;
385
+ return this;
386
+ }
387
+ toSQL() {
388
+ let query = `DELETE FROM ${getTableConfig(this._table).qualifiedName}`;
389
+ const params = [];
390
+ if (this._where.length > 0) {
391
+ const combined = sqlJoin(this._where, " AND ");
392
+ query += " WHERE " + combined.sql;
393
+ params.push(...combined.params);
394
+ }
395
+ if (this._returning) {
396
+ query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
397
+ }
398
+ return { sql: query, params };
399
+ }
400
+ }
401
+ // ../bungres-orm/src/builders/insert.ts
402
+ class InsertBuilder {
403
+ _table;
404
+ _executor;
405
+ _values = [];
406
+ _onConflict;
407
+ _returning;
408
+ _comment;
409
+ constructor(table2, executor) {
410
+ this._table = table2;
411
+ this._executor = executor;
412
+ }
413
+ then(onfulfilled, onrejected) {
414
+ return this._executor.execute(this).then(onfulfilled, onrejected);
415
+ }
416
+ async single() {
417
+ return this._executor.executeSingle(this);
418
+ }
419
+ values(data) {
420
+ if (Array.isArray(data)) {
421
+ this._values.push(...data);
422
+ } else {
423
+ this._values.push(data);
424
+ }
425
+ return this;
426
+ }
427
+ onConflictDoNothing() {
428
+ this._onConflict = "do nothing";
429
+ return this;
430
+ }
431
+ onConflict(clause) {
432
+ this._onConflict = clause;
433
+ return this;
434
+ }
435
+ returning(...columns) {
436
+ this._returning = columns.length > 0 ? columns : ["*"];
437
+ return this;
438
+ }
439
+ comment(tag) {
440
+ this._comment = tag;
441
+ return this;
442
+ }
443
+ toSQL() {
444
+ if (this._values.length === 0) {
445
+ throw new Error("InsertBuilder: no values provided");
446
+ }
447
+ const tConfig = getTableConfig(this._table);
448
+ const keySet = new Set;
449
+ for (const v of this._values) {
450
+ for (const k of Object.keys(v)) {
451
+ keySet.add(k);
452
+ }
453
+ }
454
+ const keys = Array.from(keySet);
455
+ if (keys.length === 0) {
456
+ return { sql: `INSERT INTO ${tConfig.qualifiedName} DEFAULT VALUES`, params: [] };
457
+ }
458
+ const columnsStr = keys.map((k) => `"${tConfig.columns[k]?.name ?? k}"`).join(", ");
459
+ const params = [];
460
+ const valuesStrs = this._values.map((v) => {
461
+ const vals = keys.map((k) => {
462
+ const val = v[k];
463
+ if (val && typeof val === "object" && "sql" in val && "params" in val) {
464
+ const chunk = val;
465
+ const offset = params.length;
466
+ params.push(...chunk.params);
467
+ return chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
468
+ }
469
+ if (val && typeof val === "object" && !(val instanceof Date)) {
470
+ const colType = tConfig.columns[k]?.dataType;
471
+ if (colType === "json" || colType === "jsonb") {
472
+ params.push(val);
473
+ } else if (Array.isArray(val)) {
474
+ const pgArray = "{" + val.map((item) => {
475
+ if (item === null || item === undefined)
476
+ return "NULL";
477
+ if (typeof item === "string")
478
+ return '"' + item.replace(/"/g, "\\\"") + '"';
479
+ return typeof item === "object" ? '"' + JSON.stringify(item).replace(/"/g, "\\\"") + '"' : String(item);
480
+ }).join(",") + "}";
481
+ params.push(pgArray);
482
+ } else {
483
+ params.push(JSON.stringify(val));
484
+ }
485
+ return `$${params.length}`;
486
+ }
487
+ if (val === undefined)
488
+ return "DEFAULT";
489
+ params.push(val);
490
+ return `$${params.length}`;
491
+ });
492
+ return `(${vals.join(", ")})`;
493
+ });
494
+ let query = `INSERT INTO ${tConfig.qualifiedName} (${columnsStr}) VALUES ${valuesStrs.join(", ")}`;
495
+ if (this._onConflict) {
496
+ if (this._onConflict === "do nothing") {
497
+ query += " ON CONFLICT DO NOTHING";
498
+ } else {
499
+ const offset = params.length;
500
+ query += " " + this._onConflict.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
501
+ params.push(...this._onConflict.params);
502
+ }
503
+ }
504
+ if (this._returning) {
505
+ query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(tConfig.columns).map((c) => `"${tConfig.columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${tConfig.columns[c]?.name ?? c}" AS "${c}"`).join(", "));
506
+ }
507
+ if (this._comment) {
508
+ query += ` /* ${this._comment} */`;
509
+ }
510
+ return { sql: query, params };
511
+ }
512
+ }
513
+ // ../bungres-orm/src/builders/select.ts
147
514
  class SelectBuilder {
148
515
  _table;
149
516
  _executor;
150
517
  _where = [];
151
518
  _orderBy = [];
519
+ _groupBy = [];
520
+ _having = [];
152
521
  _limit;
153
522
  _offset;
154
523
  _select;
@@ -175,11 +544,27 @@ class SelectBuilder {
175
544
  return this;
176
545
  }
177
546
  where(condition) {
178
- this._where.push(condition);
547
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
548
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
549
+ } else {
550
+ this._where.push(condition);
551
+ }
179
552
  return this;
180
553
  }
181
554
  orderBy(column, dir = "asc") {
182
- this._orderBy.push({ column: typeof column === "string" ? column : column.name, dir });
555
+ this._orderBy.push({ column, dir });
556
+ return this;
557
+ }
558
+ groupBy(...columns) {
559
+ this._groupBy.push(...columns);
560
+ return this;
561
+ }
562
+ having(condition) {
563
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
564
+ this._having.push(parseWhereObject(getTableConfig(this._table), condition));
565
+ } else {
566
+ this._having.push(condition);
567
+ }
183
568
  return this;
184
569
  }
185
570
  limit(n) {
@@ -194,35 +579,118 @@ class SelectBuilder {
194
579
  this._joins.push(rawClause);
195
580
  return this;
196
581
  }
582
+ innerJoin(table2, condition) {
583
+ this._joins.push(sql`INNER JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
584
+ return this;
585
+ }
586
+ leftJoin(table2, condition) {
587
+ this._joins.push(sql`LEFT JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
588
+ return this;
589
+ }
590
+ rightJoin(table2, condition) {
591
+ this._joins.push(sql`RIGHT JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
592
+ return this;
593
+ }
594
+ fullJoin(table2, condition) {
595
+ this._joins.push(sql`FULL JOIN ${rawSql(getTableConfig(table2).qualifiedName)} ON ${condition}`);
596
+ return this;
597
+ }
598
+ _buildSelection(selection, params) {
599
+ const parts = [];
600
+ for (const [alias, col2] of Object.entries(selection)) {
601
+ if (typeof col2 === "object" && col2 !== null) {
602
+ if ("sql" in col2 && "params" in col2) {
603
+ const chunk = col2;
604
+ const offset = params.length;
605
+ params.push(...chunk.params);
606
+ parts.push(`'${alias}', ${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)}`);
607
+ } else if ("name" in col2 && "dataType" in col2) {
608
+ const c = col2;
609
+ parts.push(`'${alias}', ${c.tableName ? c.tableName + "." : ""}"${c.name}"`);
610
+ } else {
611
+ parts.push(`'${alias}', json_build_object(${this._buildSelection(col2, params)})`);
612
+ }
613
+ }
614
+ }
615
+ return parts.join(", ");
616
+ }
197
617
  toSQL() {
198
618
  let cols = "";
619
+ const params = [];
199
620
  if (this._selection) {
200
- cols = Object.entries(this._selection).map(([alias, col2]) => `"${col2.name}" AS "${alias}"`).join(", ");
621
+ cols = Object.entries(this._selection).map(([alias, col2]) => {
622
+ if (typeof col2 === "object" && col2 !== null && "sql" in col2 && "params" in col2) {
623
+ const chunk = col2;
624
+ const offset = params.length;
625
+ params.push(...chunk.params);
626
+ return `${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)} AS "${alias}"`;
627
+ } else if (typeof col2 === "object" && col2 !== null && "name" in col2 && "dataType" in col2) {
628
+ const c = col2;
629
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}" AS "${alias}"`;
630
+ } else {
631
+ return `json_build_object(${this._buildSelection(col2, params)}) AS "${alias}"`;
632
+ }
633
+ }).join(", ");
201
634
  } else if (this._select && this._select.length > 0) {
635
+ const qName = getTableConfig(this._table).qualifiedName;
202
636
  cols = this._select.map((c) => {
203
637
  if (typeof c === "string") {
204
- return `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`;
638
+ return `${qName}."${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`;
205
639
  }
206
- return `"${c.name}" AS "${c.alias || c.name}"`;
640
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}" AS "${c.alias || c.name}"`;
207
641
  }).join(", ");
208
642
  } else {
209
- cols = Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ");
643
+ const qName = getTableConfig(this._table).qualifiedName;
644
+ cols = Object.keys(getTableConfig(this._table).columns).map((c) => `${qName}."${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ");
210
645
  }
211
646
  let query = `SELECT ${cols} FROM ${getTableConfig(this._table).qualifiedName}`;
212
647
  if (this._joins.length > 0) {
213
- query += " " + this._joins.join(" ");
648
+ const joinChunks = this._joins.map((j) => typeof j === "string" ? rawSql(j) : j);
649
+ const combinedJoins = sqlJoin(joinChunks, " ");
650
+ const offset = params.length;
651
+ query += " " + combinedJoins.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
652
+ params.push(...combinedJoins.params);
214
653
  }
215
- const params = [];
216
654
  if (this._where.length > 0) {
217
655
  const combined = sqlJoin(this._where, " AND ");
218
- const offset = 0;
656
+ const offset = params.length;
219
657
  query += " WHERE " + combined.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
220
658
  params.push(...combined.params);
221
659
  }
660
+ if (this._groupBy.length > 0) {
661
+ const qName = getTableConfig(this._table).qualifiedName;
662
+ query += " GROUP BY " + this._groupBy.map((c) => {
663
+ if (typeof c === "string") {
664
+ const dbCol = getTableConfig(this._table).columns[c]?.name ?? c;
665
+ return `${qName}."${dbCol}"`;
666
+ } else if ("sql" in c && "params" in c) {
667
+ const offset = params.length;
668
+ params.push(...c.params);
669
+ return c.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
670
+ } else {
671
+ return `${c.tableName ? c.tableName + "." : ""}"${c.name}"`;
672
+ }
673
+ }).join(", ");
674
+ }
675
+ if (this._having.length > 0) {
676
+ const combined = sqlJoin(this._having, " AND ");
677
+ const offset = params.length;
678
+ query += " HAVING " + combined.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
679
+ params.push(...combined.params);
680
+ }
222
681
  if (this._orderBy.length > 0) {
682
+ const qName = getTableConfig(this._table).qualifiedName;
223
683
  query += " ORDER BY " + this._orderBy.map((o) => {
224
- const dbCol = getTableConfig(this._table).columns[o.column]?.name ?? o.column;
225
- return `"${dbCol}" ${o.dir.toUpperCase()}`;
684
+ if (typeof o.column === "string") {
685
+ const dbCol = getTableConfig(this._table).columns[o.column]?.name ?? o.column;
686
+ return `${qName}."${dbCol}" ${o.dir.toUpperCase()}`;
687
+ } else if ("sql" in o.column && "params" in o.column) {
688
+ const offset = params.length;
689
+ params.push(...o.column.params);
690
+ return `${o.column.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)} ${o.dir.toUpperCase()}`;
691
+ } else {
692
+ return `${o.column.tableName ? o.column.tableName + "." : ""}"${o.column.name}" ${o.dir.toUpperCase()}`;
693
+ }
226
694
  }).join(", ");
227
695
  }
228
696
  if (this._limit !== undefined) {
@@ -251,76 +719,7 @@ class SelectBuilderIntermediate {
251
719
  return new SelectBuilder(table2, this._executor, this._selection);
252
720
  }
253
721
  }
254
-
255
- class InsertBuilder {
256
- _table;
257
- _executor;
258
- _values = [];
259
- _onConflict;
260
- _returning;
261
- _comment;
262
- constructor(table2, executor) {
263
- this._table = table2;
264
- this._executor = executor;
265
- }
266
- then(onfulfilled, onrejected) {
267
- return this._executor.execute(this).then(onfulfilled, onrejected);
268
- }
269
- async single() {
270
- return this._executor.executeSingle(this);
271
- }
272
- values(data) {
273
- const rows = Array.isArray(data) ? data : [data];
274
- this._values.push(...rows);
275
- return this;
276
- }
277
- onConflictDoNothing() {
278
- this._onConflict = "do nothing";
279
- return this;
280
- }
281
- onConflictDoUpdate(clause) {
282
- this._onConflict = clause;
283
- return this;
284
- }
285
- returning(...columns) {
286
- this._returning = columns.length > 0 ? columns : ["*"];
287
- return this;
288
- }
289
- comment(tag) {
290
- this._comment = tag;
291
- return this;
292
- }
293
- toSQL() {
294
- if (this._values.length === 0) {
295
- throw new Error("InsertBuilder: no values provided");
296
- }
297
- const keys = Array.from(new Set(this._values.flatMap((v) => Object.keys(v))));
298
- const params = [];
299
- const rowPlaceholders = [];
300
- for (const row of this._values) {
301
- const placeholders = [];
302
- for (const key of keys) {
303
- params.push(row[key] ?? null);
304
- placeholders.push(`$${params.length}`);
305
- }
306
- rowPlaceholders.push(`(${placeholders.join(", ")})`);
307
- }
308
- const colList = keys.map((k) => `"${getTableConfig(this._table).columns[k]?.name ?? k}"`).join(", ");
309
- let query = `INSERT INTO ${getTableConfig(this._table).qualifiedName} (${colList}) VALUES ${rowPlaceholders.join(", ")}`;
310
- if (this._onConflict === "do nothing") {
311
- query += " ON CONFLICT DO NOTHING";
312
- } else if (this._onConflict && typeof this._onConflict === "object") {
313
- const offset = params.length;
314
- query += " ON CONFLICT " + this._onConflict.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
315
- params.push(...this._onConflict.params);
316
- }
317
- if (this._returning) {
318
- query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
319
- }
320
- return { sql: query, params };
321
- }
322
- }
323
-
722
+ // ../bungres-orm/src/builders/update.ts
324
723
  class UpdateBuilder {
325
724
  _table;
326
725
  _executor;
@@ -343,7 +742,11 @@ class UpdateBuilder {
343
742
  return this;
344
743
  }
345
744
  where(condition) {
346
- this._where.push(condition);
745
+ if (condition && typeof condition === "object" && !("sql" in condition)) {
746
+ this._where.push(parseWhereObject(getTableConfig(this._table), condition));
747
+ } else {
748
+ this._where.push(condition);
749
+ }
347
750
  return this;
348
751
  }
349
752
  returning(...columns) {
@@ -361,8 +764,32 @@ class UpdateBuilder {
361
764
  }
362
765
  const params = [];
363
766
  const setClauses = entries.map(([key, value]) => {
364
- params.push(value);
365
767
  const dbCol = getTableConfig(this._table).columns[key]?.name ?? key;
768
+ if (value && typeof value === "object" && "sql" in value && "params" in value) {
769
+ const chunk = value;
770
+ const offset = params.length;
771
+ params.push(...chunk.params);
772
+ return `"${dbCol}" = ${chunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`)}`;
773
+ }
774
+ if (value && typeof value === "object" && !(value instanceof Date)) {
775
+ const colType = getTableConfig(this._table).columns[key]?.dataType;
776
+ if (colType === "json" || colType === "jsonb") {
777
+ params.push(value);
778
+ } else if (Array.isArray(value)) {
779
+ const pgArray = "{" + value.map((item) => {
780
+ if (item === null || item === undefined)
781
+ return "NULL";
782
+ if (typeof item === "string")
783
+ return '"' + item.replace(/"/g, "\\\"") + '"';
784
+ return typeof item === "object" ? '"' + JSON.stringify(item).replace(/"/g, "\\\"") + '"' : String(item);
785
+ }).join(",") + "}";
786
+ params.push(pgArray);
787
+ } else {
788
+ params.push(JSON.stringify(value));
789
+ }
790
+ return `"${dbCol}" = $${params.length}`;
791
+ }
792
+ params.push(value);
366
793
  return `"${dbCol}" = $${params.length}`;
367
794
  });
368
795
  let query = `UPDATE ${getTableConfig(this._table).qualifiedName} SET ${setClauses.join(", ")}`;
@@ -378,50 +805,7 @@ class UpdateBuilder {
378
805
  return { sql: query, params };
379
806
  }
380
807
  }
381
-
382
- class DeleteBuilder {
383
- _table;
384
- _executor;
385
- _where = [];
386
- _returning;
387
- _comment;
388
- constructor(table2, executor) {
389
- this._table = table2;
390
- this._executor = executor;
391
- }
392
- then(onfulfilled, onrejected) {
393
- return this._executor.execute(this).then(onfulfilled, onrejected);
394
- }
395
- async single() {
396
- return this._executor.executeSingle(this);
397
- }
398
- where(condition) {
399
- this._where.push(condition);
400
- return this;
401
- }
402
- returning(...columns) {
403
- this._returning = columns.length > 0 ? columns : ["*"];
404
- return this;
405
- }
406
- comment(tag) {
407
- this._comment = tag;
408
- return this;
409
- }
410
- toSQL() {
411
- let query = `DELETE FROM ${getTableConfig(this._table).qualifiedName}`;
412
- const params = [];
413
- if (this._where.length > 0) {
414
- const combined = sqlJoin(this._where, " AND ");
415
- query += " WHERE " + combined.sql;
416
- params.push(...combined.params);
417
- }
418
- if (this._returning) {
419
- query += " RETURNING " + (this._returning[0] === "*" ? Object.keys(getTableConfig(this._table).columns).map((c) => `"${getTableConfig(this._table).columns[c].name}" AS "${c}"`).join(", ") : this._returning.map((c) => `"${getTableConfig(this._table).columns[c]?.name ?? c}" AS "${c}"`).join(", "));
420
- }
421
- return { sql: query, params };
422
- }
423
- }
424
- // ../bungres-orm/src/relational.ts
808
+ // ../bungres-orm/src/builders/relational.ts
425
809
  var _relationsCache = new WeakMap;
426
810
 
427
811
  class RelationalQueryBuilder {
@@ -505,7 +889,7 @@ class RelationalQueryBuilder {
505
889
  const ones = {};
506
890
  const manys = {};
507
891
  const manyToManys = {};
508
- for (const [colName, col2] of Object.entries(tConfig.columns)) {
892
+ for (const [colName2, col2] of Object.entries(tConfig.columns)) {
509
893
  if (col2.references) {
510
894
  const ref = col2.references;
511
895
  const relName = ref.relationName || ref.table;
@@ -514,7 +898,7 @@ class RelationalQueryBuilder {
514
898
  }
515
899
  for (const [otherName, otherTable] of Object.entries(this._schema)) {
516
900
  const otherConfig = otherTable[TableConfigSymbol];
517
- for (const [colName, col2] of Object.entries(otherConfig.columns)) {
901
+ for (const [colName2, col2] of Object.entries(otherConfig.columns)) {
518
902
  if (col2.references && col2.references.table === tableName) {
519
903
  const ref = col2.references;
520
904
  const backRelName = ref.backRelationName || otherName;
@@ -553,10 +937,15 @@ class RelationalQueryBuilder {
553
937
  const jsonFields = [];
554
938
  const lateralJoins = [];
555
939
  const columnsConfig = args.columns;
940
+ const hasTrue = columnsConfig ? Object.values(columnsConfig).some((v) => v === true) : false;
556
941
  for (const [colKey, colConfig] of Object.entries(tableConfig.columns)) {
557
942
  if (columnsConfig) {
558
- if (columnsConfig[colKey] !== true) {
559
- continue;
943
+ if (hasTrue) {
944
+ if (columnsConfig[colKey] !== true)
945
+ continue;
946
+ } else {
947
+ if (columnsConfig[colKey] === false)
948
+ continue;
560
949
  }
561
950
  }
562
951
  jsonFields.push(`'${colKey}', "${alias}"."${colConfig.name}"`);
@@ -615,10 +1004,16 @@ class RelationalQueryBuilder {
615
1004
  if (joinCondition) {
616
1005
  fromSql += ` WHERE ${joinCondition}`;
617
1006
  }
618
- if (args.where && args.where.sql) {
1007
+ if (args.where) {
619
1008
  const offset = params.length;
620
- fromSql += (joinCondition ? " AND " : " WHERE ") + args.where.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
621
- params.push(...args.where.params);
1009
+ let whereChunk = args.where;
1010
+ if (args.where && !args.where.sql) {
1011
+ whereChunk = parseWhereObject(tableConfig, args.where);
1012
+ }
1013
+ if (whereChunk && whereChunk.sql) {
1014
+ fromSql += (joinCondition ? " AND " : " WHERE ") + whereChunk.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
1015
+ params.push(...whereChunk.params);
1016
+ }
622
1017
  }
623
1018
  if (args.orderBy) {
624
1019
  if (typeof args.orderBy === "string") {
@@ -627,6 +1022,15 @@ class RelationalQueryBuilder {
627
1022
  const offset = params.length;
628
1023
  fromSql += ` ORDER BY ` + args.orderBy.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
629
1024
  params.push(...args.orderBy.params);
1025
+ } else {
1026
+ const chunks = parseOrderByObject(tableConfig, args.orderBy);
1027
+ if (chunks.length > 0) {
1028
+ fromSql += ` ORDER BY ` + chunks.map((c) => {
1029
+ const offset = params.length;
1030
+ params.push(...c.params);
1031
+ return c.sql.replace(/\$(\d+)/g, (_, n) => `$${parseInt(n) + offset}`);
1032
+ }).join(", ");
1033
+ }
630
1034
  }
631
1035
  }
632
1036
  if (args.limit !== undefined) {
@@ -648,7 +1052,7 @@ class RelationalQueryBuilder {
648
1052
  }
649
1053
  }
650
1054
 
651
- // ../bungres-orm/src/db.ts
1055
+ // ../bungres-orm/src/core/db.ts
652
1056
  function parseDBName(url) {
653
1057
  try {
654
1058
  return new URL(url).pathname.slice(1);
@@ -1047,11 +1451,11 @@ function diffSchemas(prev, next) {
1047
1451
  const idxName = idx.name ?? `idx_${tableName}_${idx.columns.join("_")}`;
1048
1452
  if (!prevIdxNames.has(idxName)) {
1049
1453
  const tbl = nextConfig.schema ? `"${nextConfig.schema}"."${tableName}"` : `"${tableName}"`;
1050
- const unique = idx.unique ? "UNIQUE " : "";
1454
+ const unique2 = idx.unique ? "UNIQUE " : "";
1051
1455
  const using = idx.using ? ` USING ${idx.using.toUpperCase()}` : "";
1052
1456
  const cols = idx.columns.map((c) => `"${c}"`).join(", ");
1053
1457
  const where = idx.where ? ` WHERE ${idx.where}` : "";
1054
- statements.push(`CREATE ${unique}INDEX IF NOT EXISTS "${idxName}" ON ${tbl}${using} (${cols})${where};`);
1458
+ statements.push(`CREATE ${unique2}INDEX IF NOT EXISTS "${idxName}" ON ${tbl}${using} (${cols})${where};`);
1055
1459
  summary.push(`CREATE INDEX ${idxName} ON ${tableName}`);
1056
1460
  }
1057
1461
  }
@@ -1367,7 +1771,7 @@ Done.`, "green"));
1367
1771
  // src/commands/pull.ts
1368
1772
  import { resolve as resolve5, join as join5 } from "path";
1369
1773
  async function introspectDb(sql2, dbSchema) {
1370
- const columns = await sql2.unsafe(`SELECT
1774
+ const columns2 = await sql2.unsafe(`SELECT
1371
1775
  c.table_name,
1372
1776
  c.column_name,
1373
1777
  c.data_type,
@@ -1401,7 +1805,7 @@ async function introspectDb(sql2, dbSchema) {
1401
1805
  const indexes = await sql2.unsafe(`SELECT tablename, indexname, indexdef
1402
1806
  FROM pg_indexes
1403
1807
  WHERE schemaname = $1`, [dbSchema]);
1404
- return groupByTable(columns, constraints, indexes);
1808
+ return groupByTable(columns2, constraints, indexes);
1405
1809
  }
1406
1810
  async function runPull(config) {
1407
1811
  console.log("@bungres/kit pull: introspecting database...");
@@ -1424,9 +1828,9 @@ async function runPull(config) {
1424
1828
  await sql2.end();
1425
1829
  }
1426
1830
  }
1427
- function groupByTable(columns, constraints, indexes) {
1831
+ function groupByTable(columns2, constraints, indexes) {
1428
1832
  const map = new Map;
1429
- for (const col2 of columns) {
1833
+ for (const col2 of columns2) {
1430
1834
  if (!map.has(col2.table_name)) {
1431
1835
  map.set(col2.table_name, {
1432
1836
  tableName: col2.table_name,
@@ -1462,21 +1866,22 @@ function generateSchemaTS(tableMap, dbSchema) {
1462
1866
  `// Generated at: ${new Date().toISOString()}`,
1463
1867
  ``,
1464
1868
  `import {`,
1465
- ` table,`,
1869
+ ` snakeCase,`,
1466
1870
  ` text, varchar, char, integer, bigint, smallint,`,
1467
1871
  ` serial, bigserial, boolean, real, doublePrecision,`,
1468
1872
  ` numeric, decimal, json, jsonb,`,
1469
1873
  ` timestamp, timestamptz, date, time, uuid,`,
1470
1874
  ` bytea, inet,`,
1875
+ ` textArray, integerArray, varcharArray, uuidArray,`,
1471
1876
  `} from "@bungres/orm";`,
1472
1877
  ``
1473
1878
  ];
1474
1879
  for (const [, table2] of tableMap) {
1475
1880
  const varName = toCamelCase(table2.tableName);
1476
- lines.push(`export const ${varName} = table("${table2.tableName}", {`);
1881
+ lines.push(`export const ${varName} = snakeCase.table("${table2.tableName}", {`);
1477
1882
  for (const col2 of table2.columns) {
1478
1883
  const colExpr = buildColumnExpression(col2);
1479
- lines.push(` ${col2.name}: ${colExpr},`);
1884
+ lines.push(` ${toCamelCase(col2.name)}: ${colExpr},`);
1480
1885
  }
1481
1886
  const options = [];
1482
1887
  if (dbSchema !== "public") {
@@ -1523,84 +1928,97 @@ function generateSchemaTS(tableMap, dbSchema) {
1523
1928
  `);
1524
1929
  }
1525
1930
  function buildColumnExpression(col2) {
1526
- let expr = pgTypeToBungresBuilder(col2);
1931
+ const opts = [];
1932
+ if (col2.dataType === "character varying" || col2.dataType === "character") {
1933
+ if (col2.maxLength)
1934
+ opts.push(`length: ${col2.maxLength}`);
1935
+ }
1527
1936
  if (col2.isPrimary)
1528
- expr += `.primaryKey()`;
1937
+ opts.push(`primaryKey: true`);
1529
1938
  else if (!col2.isNullable)
1530
- expr += `.notNull()`;
1939
+ opts.push(`notNull: true`);
1531
1940
  if (col2.isUnique && !col2.isPrimary)
1532
- expr += `.unique()`;
1941
+ opts.push(`unique: true`);
1533
1942
  if (col2.columnDefault !== null && !col2.isPrimary) {
1534
1943
  if (col2.columnDefault.includes("(")) {
1535
- expr += `.defaultRaw("${col2.columnDefault}")`;
1536
- } else if (col2.dataType === "boolean") {
1537
- expr += `.default(${col2.columnDefault})`;
1538
- } else if (col2.dataType.includes("int") || col2.dataType.includes("numeric") || col2.dataType.includes("real") || col2.dataType.includes("double")) {
1539
- expr += `.default(${col2.columnDefault})`;
1944
+ opts.push(`defaultRaw: "${col2.columnDefault}"`);
1945
+ } else if (col2.dataType === "boolean" || col2.dataType.includes("int") || col2.dataType.includes("numeric") || col2.dataType.includes("real") || col2.dataType.includes("double")) {
1946
+ opts.push(`default: ${col2.columnDefault}`);
1540
1947
  } else {
1541
1948
  const cleaned = col2.columnDefault.replace(/^'(.*)'::.*$/, "$1");
1542
- expr += `.default("${cleaned}")`;
1949
+ opts.push(`default: "${cleaned}"`);
1543
1950
  }
1544
1951
  }
1545
1952
  if (col2.foreignTable && col2.foreignColumn) {
1546
1953
  const deleteRule = col2.deleteRule?.toLowerCase().replace(" ", " ");
1547
1954
  const updateRule = col2.updateRule?.toLowerCase().replace(" ", " ");
1548
- let refOpts = "";
1549
- if (deleteRule && deleteRule !== "no action") {
1550
- refOpts += `onDelete: "${deleteRule}", `;
1551
- }
1552
- if (updateRule && updateRule !== "no action") {
1553
- refOpts += `onUpdate: "${updateRule}"`;
1554
- }
1555
- const opts = refOpts ? `, { ${refOpts.trim().replace(/,$/, "")} }` : "";
1556
- expr += `.references("${col2.foreignTable}", "${col2.foreignColumn}"${opts})`;
1557
- }
1558
- return expr;
1955
+ let refOpts = `table: "${col2.foreignTable}", column: "${col2.foreignColumn}"`;
1956
+ if (deleteRule && deleteRule !== "no action")
1957
+ refOpts += `, onDelete: "${deleteRule}"`;
1958
+ if (updateRule && updateRule !== "no action")
1959
+ refOpts += `, onUpdate: "${updateRule}"`;
1960
+ opts.push(`references: { ${refOpts} }`);
1961
+ }
1962
+ let builderName = pgTypeToBungresBuilderName(col2);
1963
+ if (opts.length > 0) {
1964
+ return `${builderName}({ ${opts.join(", ")} })`;
1965
+ }
1966
+ return `${builderName}()`;
1559
1967
  }
1560
- function pgTypeToBungresBuilder(col2) {
1968
+ function pgTypeToBungresBuilderName(col2) {
1561
1969
  const dt = col2.dataType;
1562
- const name = col2.name;
1563
1970
  if (dt === "uuid")
1564
- return `uuid("${name}")`;
1971
+ return "uuid";
1565
1972
  if (dt === "text")
1566
- return `text("${name}")`;
1973
+ return "text";
1567
1974
  if (dt === "character varying")
1568
- return col2.maxLength ? `varchar("${name}", ${col2.maxLength})` : `varchar("${name}")`;
1975
+ return "varchar";
1569
1976
  if (dt === "character")
1570
- return col2.maxLength ? `char("${name}", ${col2.maxLength})` : `char("${name}")`;
1977
+ return "char";
1571
1978
  if (dt === "integer")
1572
- return `integer("${name}")`;
1979
+ return "integer";
1573
1980
  if (dt === "bigint")
1574
- return `bigint("${name}")`;
1981
+ return "bigint";
1575
1982
  if (dt === "smallint")
1576
- return `smallint("${name}")`;
1983
+ return "smallint";
1577
1984
  if (dt === "boolean")
1578
- return `boolean("${name}")`;
1985
+ return "boolean";
1579
1986
  if (dt === "real")
1580
- return `real("${name}")`;
1987
+ return "real";
1581
1988
  if (dt === "double precision")
1582
- return `doublePrecision("${name}")`;
1989
+ return "doublePrecision";
1583
1990
  if (dt === "numeric" || dt === "decimal")
1584
- return `numeric("${name}")`;
1991
+ return "numeric";
1585
1992
  if (dt === "json")
1586
- return `json("${name}")`;
1993
+ return "json";
1587
1994
  if (dt === "jsonb")
1588
- return `jsonb("${name}")`;
1995
+ return "jsonb";
1589
1996
  if (dt === "timestamp without time zone")
1590
- return `timestamp("${name}")`;
1997
+ return "timestamp";
1591
1998
  if (dt === "timestamp with time zone")
1592
- return `timestamptz("${name}")`;
1999
+ return "timestamptz";
1593
2000
  if (dt === "date")
1594
- return `date("${name}")`;
2001
+ return "date";
1595
2002
  if (dt === "time without time zone")
1596
- return `time("${name}")`;
2003
+ return "time";
1597
2004
  if (dt === "bytea")
1598
- return `bytea("${name}")`;
2005
+ return "bytea";
1599
2006
  if (dt === "inet")
1600
- return `inet("${name}")`;
2007
+ return "inet";
1601
2008
  if (dt === "USER-DEFINED" && col2.udtName === "citext")
1602
- return `text("${name}")`;
1603
- return `text("${name}") /* original type: ${dt} */`;
2009
+ return "text";
2010
+ if (dt === "ARRAY") {
2011
+ if (col2.udtName === "_text")
2012
+ return "textArray";
2013
+ if (col2.udtName === "_int4" || col2.udtName === "_int8")
2014
+ return "integerArray";
2015
+ if (col2.udtName === "_varchar")
2016
+ return "varcharArray";
2017
+ if (col2.udtName === "_uuid")
2018
+ return "uuidArray";
2019
+ return "textArray";
2020
+ }
2021
+ return "text";
1604
2022
  }
1605
2023
  function toCamelCase(str) {
1606
2024
  return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());