@dyrected/db-mysql 2.8.3 → 2.10.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.cjs CHANGED
@@ -369,6 +369,7 @@ FIX INSTRUCTIONS:
369
369
  };
370
370
  const selectParts = [];
371
371
  const allParams = [];
372
+ const isDistinctMap = {};
372
373
  for (const [name, op] of Object.entries(args.aggregates)) {
373
374
  let whereSql = null;
374
375
  if (op.where && Object.keys(op.where).length > 0) {
@@ -377,7 +378,14 @@ FIX INSTRUCTIONS:
377
378
  allParams.push(...parsed.params);
378
379
  }
379
380
  let aggExpr;
380
- if ("count" in op) {
381
+ if ("countDistinct" in op && typeof op.countDistinct === "string") {
382
+ const fieldExpr = toFieldExpr(op.countDistinct);
383
+ aggExpr = whereSql ? `COUNT(DISTINCT IF(${whereSql}, ${fieldExpr}, NULL))` : `COUNT(DISTINCT ${fieldExpr})`;
384
+ } else if ("distinct" in op && typeof op.distinct === "string") {
385
+ isDistinctMap[name] = true;
386
+ const fieldExpr = toFieldExpr(op.distinct);
387
+ aggExpr = whereSql ? `COALESCE(JSON_ARRAYAGG(DISTINCT IF(${whereSql}, ${fieldExpr}, NULL)), JSON_ARRAY())` : `COALESCE(JSON_ARRAYAGG(DISTINCT ${fieldExpr}), JSON_ARRAY())`;
388
+ } else if ("count" in op) {
381
389
  aggExpr = whereSql ? `COUNT(IF(${whereSql}, 1, NULL))` : `COUNT(*)`;
382
390
  } else if (op.sum) {
383
391
  const val = toCastExpr(op.sum, op.cast);
@@ -398,13 +406,39 @@ FIX INSTRUCTIONS:
398
406
  `${aggExpr} AS \`${name.replace(/`/g, "``")}\``
399
407
  );
400
408
  }
409
+ if (args.groupBy) {
410
+ const groupCol = toFieldExpr(args.groupBy);
411
+ const query2 = `SELECT ${groupCol} AS \`__group_key\`, ${selectParts.join(", ")} FROM \`${tableName}\` GROUP BY ${groupCol}`;
412
+ const [rows2] = await this.query(query2, allParams);
413
+ const groups = {};
414
+ for (const row2 of rows2 ?? []) {
415
+ const key = row2.__group_key === null || row2.__group_key === void 0 ? "__unassigned__" : String(row2.__group_key);
416
+ const groupResult = {};
417
+ for (const name of Object.keys(args.aggregates)) {
418
+ const raw = row2[name];
419
+ if (isDistinctMap[name]) {
420
+ const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
421
+ groupResult[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
422
+ } else {
423
+ groupResult[name] = raw === null || raw === void 0 ? null : Number(raw);
424
+ }
425
+ }
426
+ groups[key] = groupResult;
427
+ }
428
+ return { groups };
429
+ }
401
430
  const query = `SELECT ${selectParts.join(", ")} FROM \`${tableName}\``;
402
431
  const [rows] = await this.query(query, allParams);
403
432
  const row = rows[0] ?? {};
404
433
  const result = {};
405
434
  for (const name of Object.keys(args.aggregates)) {
406
435
  const raw = row[name];
407
- result[name] = raw === null || raw === void 0 ? null : Number(raw);
436
+ if (isDistinctMap[name]) {
437
+ const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
438
+ result[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
439
+ } else {
440
+ result[name] = raw === null || raw === void 0 ? null : Number(raw);
441
+ }
408
442
  }
409
443
  return result;
410
444
  }
package/dist/index.d.cts CHANGED
@@ -61,7 +61,8 @@ declare class MysqlAdapter implements DatabaseAdapter {
61
61
  aggregate(args: {
62
62
  collection: string;
63
63
  aggregates: Record<string, any>;
64
- }): Promise<Record<string, number | null>>;
64
+ groupBy?: string;
65
+ }): Promise<Record<string, any>>;
65
66
  disconnect(): Promise<void>;
66
67
  }
67
68
  declare const mysqlAdapter: (config: MysqlAdapterConfig) => MysqlAdapter;
package/dist/index.d.ts CHANGED
@@ -61,7 +61,8 @@ declare class MysqlAdapter implements DatabaseAdapter {
61
61
  aggregate(args: {
62
62
  collection: string;
63
63
  aggregates: Record<string, any>;
64
- }): Promise<Record<string, number | null>>;
64
+ groupBy?: string;
65
+ }): Promise<Record<string, any>>;
65
66
  disconnect(): Promise<void>;
66
67
  }
67
68
  declare const mysqlAdapter: (config: MysqlAdapterConfig) => MysqlAdapter;
package/dist/index.js CHANGED
@@ -334,6 +334,7 @@ FIX INSTRUCTIONS:
334
334
  };
335
335
  const selectParts = [];
336
336
  const allParams = [];
337
+ const isDistinctMap = {};
337
338
  for (const [name, op] of Object.entries(args.aggregates)) {
338
339
  let whereSql = null;
339
340
  if (op.where && Object.keys(op.where).length > 0) {
@@ -342,7 +343,14 @@ FIX INSTRUCTIONS:
342
343
  allParams.push(...parsed.params);
343
344
  }
344
345
  let aggExpr;
345
- if ("count" in op) {
346
+ if ("countDistinct" in op && typeof op.countDistinct === "string") {
347
+ const fieldExpr = toFieldExpr(op.countDistinct);
348
+ aggExpr = whereSql ? `COUNT(DISTINCT IF(${whereSql}, ${fieldExpr}, NULL))` : `COUNT(DISTINCT ${fieldExpr})`;
349
+ } else if ("distinct" in op && typeof op.distinct === "string") {
350
+ isDistinctMap[name] = true;
351
+ const fieldExpr = toFieldExpr(op.distinct);
352
+ aggExpr = whereSql ? `COALESCE(JSON_ARRAYAGG(DISTINCT IF(${whereSql}, ${fieldExpr}, NULL)), JSON_ARRAY())` : `COALESCE(JSON_ARRAYAGG(DISTINCT ${fieldExpr}), JSON_ARRAY())`;
353
+ } else if ("count" in op) {
346
354
  aggExpr = whereSql ? `COUNT(IF(${whereSql}, 1, NULL))` : `COUNT(*)`;
347
355
  } else if (op.sum) {
348
356
  const val = toCastExpr(op.sum, op.cast);
@@ -363,13 +371,39 @@ FIX INSTRUCTIONS:
363
371
  `${aggExpr} AS \`${name.replace(/`/g, "``")}\``
364
372
  );
365
373
  }
374
+ if (args.groupBy) {
375
+ const groupCol = toFieldExpr(args.groupBy);
376
+ const query2 = `SELECT ${groupCol} AS \`__group_key\`, ${selectParts.join(", ")} FROM \`${tableName}\` GROUP BY ${groupCol}`;
377
+ const [rows2] = await this.query(query2, allParams);
378
+ const groups = {};
379
+ for (const row2 of rows2 ?? []) {
380
+ const key = row2.__group_key === null || row2.__group_key === void 0 ? "__unassigned__" : String(row2.__group_key);
381
+ const groupResult = {};
382
+ for (const name of Object.keys(args.aggregates)) {
383
+ const raw = row2[name];
384
+ if (isDistinctMap[name]) {
385
+ const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
386
+ groupResult[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
387
+ } else {
388
+ groupResult[name] = raw === null || raw === void 0 ? null : Number(raw);
389
+ }
390
+ }
391
+ groups[key] = groupResult;
392
+ }
393
+ return { groups };
394
+ }
366
395
  const query = `SELECT ${selectParts.join(", ")} FROM \`${tableName}\``;
367
396
  const [rows] = await this.query(query, allParams);
368
397
  const row = rows[0] ?? {};
369
398
  const result = {};
370
399
  for (const name of Object.keys(args.aggregates)) {
371
400
  const raw = row[name];
372
- result[name] = raw === null || raw === void 0 ? null : Number(raw);
401
+ if (isDistinctMap[name]) {
402
+ const parsed = Array.isArray(raw) ? raw : typeof raw === "string" ? JSON.parse(raw) : raw ?? [];
403
+ result[name] = Array.isArray(parsed) ? parsed.filter((v) => v !== null && v !== void 0) : [];
404
+ } else {
405
+ result[name] = raw === null || raw === void 0 ? null : Number(raw);
406
+ }
373
407
  }
374
408
  return result;
375
409
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyrected/db-mysql",
3
- "version": "2.8.3",
3
+ "version": "2.10.0",
4
4
  "description": "MySQL adapter for Dyrected CMS",
5
5
  "type": "module",
6
6
  "files": [
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "mysql2": "^3.22.3",
21
- "@dyrected/core": "^2.8.3"
21
+ "@dyrected/core": "^2.10.0"
22
22
  },
23
23
  "devDependencies": {
24
24
  "tsup": "^8.0.0",