vona-module-a-orm 5.1.39 → 5.1.40

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.
Files changed (46) hide show
  1. package/dist/.metadata/index.d.ts +18 -18
  2. package/dist/.metadata/index.d.ts.map +1 -1
  3. package/dist/index.js +358 -48
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/aggregateResult.d.ts +7 -0
  6. package/dist/lib/aggregateResult.d.ts.map +1 -0
  7. package/dist/lib/analysis/controls.d.ts +27 -0
  8. package/dist/lib/analysis/controls.d.ts.map +1 -0
  9. package/dist/lib/analysis/execute.d.ts +6 -0
  10. package/dist/lib/analysis/execute.d.ts.map +1 -0
  11. package/dist/lib/analysis/index.d.ts +4 -0
  12. package/dist/lib/analysis/index.d.ts.map +1 -0
  13. package/dist/lib/analysis/policy.d.ts +6 -0
  14. package/dist/lib/analysis/policy.d.ts.map +1 -0
  15. package/dist/lib/bean.model/bean.model_cache.d.ts.map +1 -1
  16. package/dist/lib/bean.model/bean.model_crud_inner.d.ts +1 -1
  17. package/dist/lib/bean.model/bean.model_crud_inner.d.ts.map +1 -1
  18. package/dist/lib/dto/dto.d.ts +3 -0
  19. package/dist/lib/dto/dto.d.ts.map +1 -1
  20. package/dist/lib/dto/dtoAggregate.d.ts.map +1 -1
  21. package/dist/lib/dto/dtoAnalysis.d.ts +6 -0
  22. package/dist/lib/dto/dtoAnalysis.d.ts.map +1 -0
  23. package/dist/lib/index.d.ts +1 -0
  24. package/dist/lib/index.d.ts.map +1 -1
  25. package/dist/types/analysis.d.ts +105 -0
  26. package/dist/types/analysis.d.ts.map +1 -0
  27. package/dist/types/index.d.ts +1 -0
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/relationsAggr.d.ts +1 -1
  30. package/dist/types/relationsAggr.d.ts.map +1 -1
  31. package/package.json +2 -2
  32. package/src/.metadata/index.ts +26 -26
  33. package/src/lib/aggregateResult.ts +53 -0
  34. package/src/lib/analysis/controls.ts +163 -0
  35. package/src/lib/analysis/execute.ts +49 -0
  36. package/src/lib/analysis/index.ts +3 -0
  37. package/src/lib/analysis/policy.ts +140 -0
  38. package/src/lib/bean.model/bean.model_cache.ts +4 -2
  39. package/src/lib/bean.model/bean.model_crud_inner.ts +8 -3
  40. package/src/lib/dto/dto.ts +3 -0
  41. package/src/lib/dto/dtoAggregate.ts +4 -1
  42. package/src/lib/dto/dtoAnalysis.ts +34 -0
  43. package/src/lib/index.ts +1 -0
  44. package/src/types/analysis.ts +137 -0
  45. package/src/types/index.ts +1 -0
  46. package/src/types/relationsAggr.ts +1 -1
@@ -1,3 +1,21 @@
1
+ /** schedule: begin */
2
+ export * from '../bean/schedule.softDeletionPrune.ts';
3
+ import { type IDecoratorScheduleOptions } from 'vona-module-a-schedule';
4
+ declare module 'vona-module-a-schedule' {
5
+ interface IScheduleRecord {
6
+ 'a-orm:softDeletionPrune': IDecoratorScheduleOptions;
7
+ }
8
+ }
9
+ declare module 'vona-module-a-orm' {
10
+ interface ScheduleSoftDeletionPrune {
11
+ }
12
+ interface ScheduleSoftDeletionPrune {
13
+ get $beanFullName(): 'a-orm.schedule.softDeletionPrune';
14
+ get $onionName(): 'a-orm:softDeletionPrune';
15
+ get $onionOptions(): IDecoratorScheduleOptions;
16
+ }
17
+ }
18
+ /** schedule: end */
1
19
  /** aopMethod: begin */
2
20
  export * from '../bean/aopMethod.transaction.ts';
3
21
  import type { IAopMethodOptionsTransaction } from '../bean/aopMethod.transaction.ts';
@@ -199,24 +217,6 @@ export interface IModuleQueue {
199
217
  'doubleDelete': QueueDoubleDelete;
200
218
  }
201
219
  /** queue: end */
202
- /** schedule: begin */
203
- export * from '../bean/schedule.softDeletionPrune.ts';
204
- import { type IDecoratorScheduleOptions } from 'vona-module-a-schedule';
205
- declare module 'vona-module-a-schedule' {
206
- interface IScheduleRecord {
207
- 'a-orm:softDeletionPrune': IDecoratorScheduleOptions;
208
- }
209
- }
210
- declare module 'vona-module-a-orm' {
211
- interface ScheduleSoftDeletionPrune {
212
- }
213
- interface ScheduleSoftDeletionPrune {
214
- get $beanFullName(): 'a-orm.schedule.softDeletionPrune';
215
- get $onionName(): 'a-orm:softDeletionPrune';
216
- get $onionOptions(): IDecoratorScheduleOptions;
217
- }
218
- }
219
- /** schedule: end */
220
220
  /** config: begin */
221
221
  export * from '../config/config.ts';
222
222
  import type { config } from '../config/config.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/.metadata/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/.metadata/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import BigNumber from 'bignumber.js';
2
- import { BeanInfo, BeanAopMethodBase, BeanBase, deepExtend, appResource, assertIsolatedTestDatabaseClient, assertTestClaimDatabaseClient, beanFullNameFromOnionName, cast, useApp, $makeLocaleMagic, Virtual, registerTestClaimDatabaseCreation, BeanSimple, combineConfigDefault, BeanScopeBase, createBeanDecorator, PickClassInner, $Class, disposeInstance } from 'vona';
2
+ import { BeanInfo, BeanBase, BeanAopMethodBase, deepExtend, appResource, assertIsolatedTestDatabaseClient, assertTestClaimDatabaseClient, beanFullNameFromOnionName, cast, useApp, $makeLocaleMagic, Virtual, registerTestClaimDatabaseCreation, BeanSimple, combineConfigDefault, BeanScopeBase, createBeanDecorator, PickClassInner, $Class, disposeInstance } from 'vona';
3
3
  import { __decorate, __metadata } from 'tslib';
4
+ import { Schedule } from 'vona-module-a-schedule';
4
5
  import { AopMethod } from 'vona-module-a-aspect';
5
6
  import { Service, Bean, Scope } from 'vona-module-a-bean';
6
7
  import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';
@@ -9,18 +10,58 @@ import knex from 'knex';
9
10
  import { BeanMutateBase } from 'vona-module-a-beanmutate';
10
11
  import { swapDeps } from '@cabloy/deps';
11
12
  import { $tableNameFromEntity, $tableDefaults, $columnsAll } from 'vona-module-a-ormutils';
12
- import { prepareClassType, Api, v, schemaRenderVisible, getSchemaDynamic, SymbolSchemaDynamicRefId, addSchemaDynamic, getTargetDecoratorRuleColumns, mergeTargetDecoratorDtoOpenapi, mergeDtoFieldsOpenapiMetadata } from 'vona-module-a-openapiutils';
13
+ import { prepareClassType, Api, v, getTargetDecoratorRules, schemaRenderVisible, getSchemaDynamic, SymbolSchemaDynamicRefId, addSchemaDynamic, getTargetDecoratorRuleColumns, mergeTargetDecoratorDtoOpenapi, mergeDtoFieldsOpenapiMetadata } from 'vona-module-a-openapiutils';
13
14
  import z from 'zod';
14
15
  import { Broadcast, BeanBroadcastBase } from 'vona-module-a-broadcast';
15
16
  import { Event, BeanEventBase } from 'vona-module-a-event';
16
17
  import { Hmr } from 'vona-module-a-hmrbase';
17
18
  import { Queue, BeanQueueBase } from 'vona-module-a-queue';
18
- import { Schedule } from 'vona-module-a-schedule';
19
19
  import { configAll, configRedis } from 'vona-module-a-summer';
20
20
  import { ServiceDatabaseAsyncLocalStorage as ServiceDatabaseAsyncLocalStorage$1, ServiceTransactionConsistency‌ as ServiceTransactionConsistency_ } from 'vona-module-a-orm';
21
+ import { ZodMetadata } from '@cabloy/zod-openapi';
21
22
  import { mutate } from 'mutate-on-copy';
22
23
  import { parseFirstWord, toLowerCaseFirstChar } from '@cabloy/word-utils';
23
24
 
25
+ let ScheduleSoftDeletionPrune = class ScheduleSoftDeletionPrune extends BeanBase {
26
+ async execute() {
27
+ const onionSlices = this.bean.onion.model.getOnionsEnabledCached();
28
+ for (const onionSlice of onionSlices) {
29
+ if (onionSlice.beanOptions.options?.disableDeleted) continue;
30
+ let softDeletionPrune = onionSlice.beanOptions.options?.softDeletionPrune ?? this.scope.config.softDeletionPrune.enable;
31
+ if (!softDeletionPrune) continue;
32
+ if (softDeletionPrune === true) softDeletionPrune = {};
33
+ await this._modulePrune(onionSlice, softDeletionPrune);
34
+ }
35
+ }
36
+ async _modulePrune(onionSlice, softDeletionPrune) {
37
+ const handler = softDeletionPrune.handler;
38
+ const expired = softDeletionPrune.expired ?? this.scope.config.softDeletionPrune.expired;
39
+ const modelTarget = this.bean._getBean(onionSlice.beanOptions.beanFullName);
40
+ if (handler) {
41
+ await handler(this.ctx, modelTarget, {
42
+ expired
43
+ });
44
+ } else {
45
+ const expiredTime = new Date(Date.now() - expired);
46
+ await modelTarget.delete({
47
+ deleted: true,
48
+ updatedAt: {
49
+ _lt_: expiredTime
50
+ }
51
+ }, {
52
+ disableDeleted: true
53
+ });
54
+ }
55
+ }
56
+ };
57
+ ScheduleSoftDeletionPrune = __decorate([Schedule({
58
+ repeat: {
59
+ every: 24 * 3600 * 1000
60
+ }
61
+ }), BeanInfo({
62
+ module: "a-orm"
63
+ })], ScheduleSoftDeletionPrune);
64
+
24
65
  let AopMethodTransaction = class AopMethodTransaction extends BeanAopMethodBase {
25
66
  execute(options, _args, next, _receiver, _prop) {
26
67
  return this.bean.database.current.transaction.begin(() => {
@@ -781,6 +822,50 @@ BeanDatabase = __decorate([Bean(), BeanInfo({
781
822
  module: "a-orm"
782
823
  })], BeanDatabase);
783
824
 
825
+ function normalizeAggregateValue(value, fn) {
826
+ if (value === undefined) return value;
827
+ if (value === null && fn !== 'count') return value;
828
+ if (typeof value === 'string') {
829
+ if (fn !== 'count' || /^(0|[1-9]\d*)$/.test(value)) return value;
830
+ } else if (typeof value === 'number') {
831
+ if (Number.isFinite(value) && (fn !== 'count' || Number.isSafeInteger(value) && value >= 0)) {
832
+ return String(value);
833
+ }
834
+ } else if (typeof value === 'bigint' && (fn !== 'count' || value >= 0n)) {
835
+ return String(value);
836
+ }
837
+ throw new TypeError(`Invalid ORM ${fn} aggregate result`);
838
+ }
839
+ function normalizeAggregateRows(rows, aggrs) {
840
+ if (!aggrs || rows.length === 0) return rows;
841
+ const aliases = [];
842
+ for (const fn of ['count', 'sum', 'avg', 'min', 'max']) {
843
+ const columns = aggrs[fn];
844
+ if (columns === undefined) continue;
845
+ for (const column of typeof columns === 'object' ? columns : [columns]) {
846
+ aliases.push([`${fn}_${column === '*' ? 'all' : String(column)}`, fn]);
847
+ }
848
+ }
849
+ let result = rows;
850
+ for (const [index, row] of rows.entries()) {
851
+ let target = row;
852
+ for (const [alias, fn] of aliases) {
853
+ if (!Object.hasOwn(row, alias)) continue;
854
+ const value = row[alias];
855
+ const normalized = normalizeAggregateValue(value, fn);
856
+ if (value === normalized) continue;
857
+ if (target === row) target = {
858
+ ...row
859
+ };
860
+ target[alias] = normalized;
861
+ }
862
+ if (target === row) continue;
863
+ if (result === rows) result = [...rows];
864
+ result[index] = target;
865
+ }
866
+ return result;
867
+ }
868
+
784
869
  const OpAggrs = ['count', 'sum', 'avg', 'max', 'min'];
785
870
  const OpJoint = {
786
871
  and: '_and_',
@@ -1764,7 +1849,8 @@ class BeanModelCrudInner extends BeanModelView {
1764
1849
  }
1765
1850
  return `model.select: ${tip}, ${builder.toQuery()}`;
1766
1851
  });
1767
- return await this.dialect.select(builder, datas, () => this.columns(table));
1852
+ const rows = await this.dialect.select(builder, datas, () => this.columns(table));
1853
+ return normalizeAggregateRows(rows, params?.aggrs);
1768
1854
  }
1769
1855
  _select_buildParams(table, params, options) {
1770
1856
  // builder
@@ -1827,7 +1913,7 @@ class BeanModelCrudInner extends BeanModelView {
1827
1913
  // ready
1828
1914
  this.$loggerChild('model').debug(() => `model.count: ${builder.toQuery()}`);
1829
1915
  const res = await builder;
1830
- return this.extractFirstNumber(res);
1916
+ return normalizeAggregateValue(this.extractFirstValue(res), 'count');
1831
1917
  }
1832
1918
  async _increment(table, params, options) {
1833
1919
  // table
@@ -3080,46 +3166,6 @@ QueueDoubleDelete = __decorate([Queue({
3080
3166
  module: "a-orm"
3081
3167
  })], QueueDoubleDelete);
3082
3168
 
3083
- let ScheduleSoftDeletionPrune = class ScheduleSoftDeletionPrune extends BeanBase {
3084
- async execute() {
3085
- const onionSlices = this.bean.onion.model.getOnionsEnabledCached();
3086
- for (const onionSlice of onionSlices) {
3087
- if (onionSlice.beanOptions.options?.disableDeleted) continue;
3088
- let softDeletionPrune = onionSlice.beanOptions.options?.softDeletionPrune ?? this.scope.config.softDeletionPrune.enable;
3089
- if (!softDeletionPrune) continue;
3090
- if (softDeletionPrune === true) softDeletionPrune = {};
3091
- await this._modulePrune(onionSlice, softDeletionPrune);
3092
- }
3093
- }
3094
- async _modulePrune(onionSlice, softDeletionPrune) {
3095
- const handler = softDeletionPrune.handler;
3096
- const expired = softDeletionPrune.expired ?? this.scope.config.softDeletionPrune.expired;
3097
- const modelTarget = this.bean._getBean(onionSlice.beanOptions.beanFullName);
3098
- if (handler) {
3099
- await handler(this.ctx, modelTarget, {
3100
- expired
3101
- });
3102
- } else {
3103
- const expiredTime = new Date(Date.now() - expired);
3104
- await modelTarget.delete({
3105
- deleted: true,
3106
- updatedAt: {
3107
- _lt_: expiredTime
3108
- }
3109
- }, {
3110
- disableDeleted: true
3111
- });
3112
- }
3113
- }
3114
- };
3115
- ScheduleSoftDeletionPrune = __decorate([Schedule({
3116
- repeat: {
3117
- every: 24 * 3600 * 1000
3118
- }
3119
- }), BeanInfo({
3120
- module: "a-orm"
3121
- })], ScheduleSoftDeletionPrune);
3122
-
3123
3169
  function config(_app) {
3124
3170
  return {
3125
3171
  sharding: {
@@ -3332,6 +3378,255 @@ ScopeModuleAOrm = __decorate([Scope(), BeanInfo({
3332
3378
  })], ScopeModuleAOrm);
3333
3379
  /** scope: end */
3334
3380
 
3381
+ const analysisFunctions = ['count', 'sum', 'avg', 'min', 'max'];
3382
+ const analysisReservedFields = new Set(['groups', 'aggrs', 'where', 'joins', 'having', 'columns', 'orders', 'limit', 'offset', 'pageNo', 'pageSize', 'distinct', 'include', 'with']);
3383
+ /** A deliberate validation/resource-bound error, also usable without an application context. */
3384
+ class AnalysisError extends Error {
3385
+ constructor(...args) {
3386
+ super(...args);
3387
+ this.code = 422;
3388
+ this.status = 422;
3389
+ }
3390
+ }
3391
+ function analysisFailure(message) {
3392
+ throw new AnalysisError(message);
3393
+ }
3394
+ function actionDefaults(policy, mode) {
3395
+ if (mode !== 'group' && mode !== 'aggregate') analysisFailure('Unknown analysis action');
3396
+ const defaults = policy.defaults[mode];
3397
+ if (!defaults) analysisFailure(`Analysis ${mode} action is not enabled`);
3398
+ return defaults;
3399
+ }
3400
+ function columnArray(columns, max) {
3401
+ return z.array(z.enum([...columns])).min(1).max(max).superRefine((value, ctx) => {
3402
+ if (new Set(value).size !== value.length) {
3403
+ ctx.addIssue({
3404
+ code: 'custom',
3405
+ message: 'Duplicate analysis columns are not allowed'
3406
+ });
3407
+ }
3408
+ });
3409
+ }
3410
+ /** Native array/object schemas preserve finite enums for query coercion and OpenAPI. */
3411
+ function analysisControlSchemas(policy, mode) {
3412
+ const defaults = actionDefaults(policy, mode);
3413
+ const shape = {};
3414
+ for (const fn of analysisFunctions) {
3415
+ const columns = policy.aggrs[fn];
3416
+ if (columns) shape[fn] = columnArray(columns, policy.limits.maxMetrics).optional();
3417
+ }
3418
+ const aggrs = z.strictObject(shape).superRefine((value, ctx) => {
3419
+ const count = Object.values(value).reduce((total, columns) => total + (Array.isArray(columns) ? columns.length : 0), 0);
3420
+ if (count === 0 || count > policy.limits.maxMetrics) {
3421
+ ctx.addIssue({
3422
+ code: 'custom',
3423
+ message: `Analysis requires 1 to ${policy.limits.maxMetrics} metrics`
3424
+ });
3425
+ }
3426
+ }).default(() => Object.fromEntries(Object.entries(defaults.aggrs).map(([fn, columns]) => [fn, [...columns]])));
3427
+ const groups = mode === 'group' ? columnArray(policy.groups, policy.limits.maxGroups).default(() => [...defaults.groups]) : undefined;
3428
+ const selection = z.strictObject({
3429
+ groups: groups ?? z.never().optional(),
3430
+ aggrs
3431
+ });
3432
+ return {
3433
+ groups,
3434
+ aggrs,
3435
+ selection
3436
+ };
3437
+ }
3438
+ /** Validate controls independently of row filters and ignored list controls. */
3439
+ function resolveAnalysis(policy, mode, input) {
3440
+ if (input !== undefined && (!input || typeof input !== 'object' || Array.isArray(input))) {
3441
+ analysisFailure('Analysis parameters must be an object');
3442
+ }
3443
+ const params = input ?? {};
3444
+ for (const key of ['joins', 'having', 'distinct', 'include', 'with']) {
3445
+ if (Object.hasOwn(params, key) && params[key] !== undefined) {
3446
+ analysisFailure(`Analysis does not support ${key}`);
3447
+ }
3448
+ }
3449
+ if (mode === 'aggregate' && Object.hasOwn(params, 'groups')) {
3450
+ analysisFailure('Aggregate analysis does not support groups');
3451
+ }
3452
+ // The request context can enable generic query coercion. Direct service calls must
3453
+ // still supply native arrays/objects, never JSON strings or coerced scalar items.
3454
+ const assertNativeColumns = columns => {
3455
+ if (!Array.isArray(columns) || columns.some(column => typeof column !== 'string')) {
3456
+ analysisFailure('Analysis columns must be arrays of strings');
3457
+ }
3458
+ };
3459
+ if (params.groups !== undefined) assertNativeColumns(params.groups);
3460
+ if (params.aggrs !== undefined) {
3461
+ if (!params.aggrs || typeof params.aggrs !== 'object' || Array.isArray(params.aggrs)) {
3462
+ analysisFailure('Analysis metrics must be an object of column arrays');
3463
+ }
3464
+ for (const columns of Object.values(params.aggrs)) assertNativeColumns(columns);
3465
+ }
3466
+ const parsed = analysisControlSchemas(policy, mode).selection.safeParse({
3467
+ ...(mode === 'group' ? {
3468
+ groups: params.groups
3469
+ } : {}),
3470
+ aggrs: params.aggrs
3471
+ });
3472
+ if (!parsed.success) analysisFailure(parsed.error.message);
3473
+ const result = {
3474
+ aggrs: {}
3475
+ };
3476
+ if (mode === 'group') {
3477
+ // Canonical policy order also stabilizes SQL/cache keys for equivalent selections.
3478
+ const selected = parsed.data.groups;
3479
+ result.groups = policy.groups.filter(column => selected.includes(column));
3480
+ }
3481
+ for (const fn of analysisFunctions) {
3482
+ const selected = parsed.data.aggrs[fn];
3483
+ if (selected) result.aggrs[fn] = policy.aggrs[fn].filter(column => selected.includes(column));
3484
+ }
3485
+ return result;
3486
+ }
3487
+ function analysisCapabilities(policy, mode) {
3488
+ const defaults = actionDefaults(policy, mode);
3489
+ return {
3490
+ mode,
3491
+ groups: mode === 'group' ? [...policy.groups] : [],
3492
+ aggrs: Object.fromEntries(Object.entries(policy.aggrs).map(([fn, columns]) => [fn, [...columns]])),
3493
+ defaults: {
3494
+ ...(mode === 'group' ? {
3495
+ groups: [...defaults.groups]
3496
+ } : {}),
3497
+ aggrs: Object.fromEntries(Object.entries(defaults.aggrs).map(([fn, columns]) => [fn, [...columns]]))
3498
+ },
3499
+ limits: {
3500
+ ...policy.limits
3501
+ }
3502
+ };
3503
+ }
3504
+
3505
+ function assertModel(model, policy) {
3506
+ if (!(model instanceof policy.modelClass)) analysisFailure('Analysis policy does not belong to this model');
3507
+ }
3508
+ /** Keep instance/soft-delete scope, caching and scalar normalization owned by the ORM. */
3509
+ async function $executeAnalysisGroup(model, policy, params) {
3510
+ assertModel(model, policy);
3511
+ const {
3512
+ groups,
3513
+ aggrs
3514
+ } = resolveAnalysis(policy, 'group', params);
3515
+ const rows = await model.group({
3516
+ where: params?.where,
3517
+ groups: groups,
3518
+ aggrs,
3519
+ orders: groups.map(column => [column, 'asc']),
3520
+ limit: policy.limits.maxGroupRows + 1
3521
+ });
3522
+ if (rows.length > policy.limits.maxGroupRows) analysisFailure(`Analysis exceeds ${policy.limits.maxGroupRows} group rows`);
3523
+ return rows;
3524
+ }
3525
+ async function $executeAnalysisAggregate(model, policy, params) {
3526
+ assertModel(model, policy);
3527
+ const {
3528
+ aggrs
3529
+ } = resolveAnalysis(policy, 'aggregate', params);
3530
+ return await model.aggregate({
3531
+ where: params?.where,
3532
+ aggrs
3533
+ });
3534
+ }
3535
+
3536
+ function invalid(message) {
3537
+ throw new TypeError(`Invalid analysis policy: ${message}`);
3538
+ }
3539
+ function assertColumns(columns, label, allowEmpty = false) {
3540
+ if (!Array.isArray(columns) || !allowEmpty && columns.length === 0) invalid(`${label} must be a nonempty column array`);
3541
+ if (columns.some(column => typeof column !== 'string')) invalid(`${label} columns must be strings`);
3542
+ if (new Set(columns).size !== columns.length) invalid(`${label} contains duplicate columns`);
3543
+ }
3544
+ function copyAggrs(aggrs) {
3545
+ return Object.freeze(Object.fromEntries(Object.entries(aggrs).map(([fn, columns]) => [fn, Object.freeze([...columns])])));
3546
+ }
3547
+ /** Static model/entity metadata only: safe while DTO classes are being evaluated. */
3548
+ function $defineAnalysis(modelLike, config) {
3549
+ const modelClass = prepareClassModel(modelLike);
3550
+ const entityClass = getClassEntityFromClassModel(modelClass);
3551
+ const rules = getTargetDecoratorRules(entityClass.prototype, true);
3552
+ assertColumns(config.groups, 'groups', true);
3553
+ const validateField = (column, numeric) => {
3554
+ if (!/^[A-Z_]\w*$/i.test(column) || analysisReservedFields.has(column)) invalid(`unsupported column ${column}`);
3555
+ if (!Object.hasOwn(rules, column)) invalid(`unknown entity column ${column}`);
3556
+ const schema = ZodMetadata.unwrapChained(ZodMetadata.resolveLazySchema(rules[column]));
3557
+ if (numeric && (column === 'id' || column === 'iid' || schema.def.type !== 'number')) invalid(`non-count metrics require numeric columns: ${column}`);
3558
+ };
3559
+ for (const column of config.groups) validateField(column, false);
3560
+ if (!config.aggrs || typeof config.aggrs !== 'object' || Array.isArray(config.aggrs)) invalid('aggrs must be an object');
3561
+ const aliases = new Set(config.groups);
3562
+ let metricCount = 0;
3563
+ for (const [fn, columns] of Object.entries(config.aggrs)) {
3564
+ if (!analysisFunctions.includes(fn)) invalid(`unsupported function ${fn}`);
3565
+ assertColumns(columns, fn);
3566
+ for (const column of columns) {
3567
+ if (column !== '*' || fn !== 'count') validateField(column, fn !== 'count');
3568
+ const alias = `${fn}_${column === '*' ? 'all' : column}`;
3569
+ if (aliases.has(alias) || analysisReservedFields.has(alias)) invalid(`alias collision: ${alias}`);
3570
+ aliases.add(alias);
3571
+ metricCount++;
3572
+ }
3573
+ }
3574
+ if (metricCount === 0) invalid('at least one allowed metric is required');
3575
+ const limits = {
3576
+ maxGroups: 3,
3577
+ maxMetrics: 10,
3578
+ maxGroupRows: 1000,
3579
+ ...config.limits
3580
+ };
3581
+ for (const [key, value] of Object.entries(limits)) {
3582
+ if (!['maxGroups', 'maxMetrics', 'maxGroupRows'].includes(key) || !Number.isSafeInteger(value) || value < 1 || value >= Number.MAX_SAFE_INTEGER) {
3583
+ invalid(`invalid limit ${key}`);
3584
+ }
3585
+ }
3586
+ if (!config.defaults || Object.keys(config.defaults).some(key => key !== 'group' && key !== 'aggregate')) {
3587
+ invalid('unknown or missing action defaults');
3588
+ }
3589
+ if (!config.defaults.group && !config.defaults.aggregate) invalid('at least one action default is required');
3590
+ const policy = {
3591
+ modelLike,
3592
+ modelClass,
3593
+ groups: Object.freeze([...config.groups]),
3594
+ aggrs: copyAggrs(config.aggrs),
3595
+ defaults: {},
3596
+ limits: Object.freeze(limits)
3597
+ };
3598
+ const defaults = {};
3599
+ for (const mode of ['group', 'aggregate']) {
3600
+ const input = config.defaults[mode];
3601
+ if (!input) continue;
3602
+ // Do not allow omitted defaults to expand authorization implicitly.
3603
+ if (!Object.hasOwn(input, 'aggrs') || mode === 'group' && !Object.hasOwn(input, 'groups')) invalid(`incomplete ${mode} defaults`);
3604
+ if (Object.keys(input).some(key => key !== 'aggrs' && !(mode === 'group' && key === 'groups'))) invalid(`unsupported ${mode} default control`);
3605
+ const forValidation = {
3606
+ ...policy,
3607
+ defaults: {
3608
+ [mode]: input
3609
+ }
3610
+ };
3611
+ try {
3612
+ const resolved = resolveAnalysis(forValidation, mode, input);
3613
+ const aggrs = copyAggrs(resolved.aggrs);
3614
+ if (mode === 'group') defaults.group = Object.freeze({
3615
+ groups: Object.freeze(resolved.groups),
3616
+ aggrs
3617
+ });else defaults.aggregate = Object.freeze({
3618
+ aggrs
3619
+ });
3620
+ } catch (error) {
3621
+ invalid(`${mode} defaults: ${error.message}`);
3622
+ }
3623
+ }
3624
+ return Object.freeze({
3625
+ ...policy,
3626
+ defaults: Object.freeze(defaults)
3627
+ });
3628
+ }
3629
+
3335
3630
  function DatabaseDialect(options) {
3336
3631
  return createBeanDecorator('databaseDialect', options);
3337
3632
  }
@@ -3349,7 +3644,7 @@ function _DtoAggregate_inner(classTarget, _modelLike, aggrs) {
3349
3644
  if (!columns) continue;
3350
3645
  for (const column of columns) {
3351
3646
  const column2 = `${key}_${column === '*' ? 'all' : column}`;
3352
- Api.field(v.optional(), z.string())(classTarget.prototype, column2);
3647
+ Api.field(v.optional(), key === 'count' ? z.string() : z.string().nullable())(classTarget.prototype, column2);
3353
3648
  }
3354
3649
  }
3355
3650
  return classTarget;
@@ -3377,6 +3672,19 @@ function _DtoGroup_raw(modelLike, groups, aggrs, columns) {
3377
3672
  return TargetClass;
3378
3673
  }
3379
3674
 
3675
+ /** A finite optional superset: absent fields are unrequested, null retains SQL meaning. */
3676
+ function DtoAnalysisGroup(policy) {
3677
+ if (!policy.defaults.group) throw new TypeError('Analysis group action is not enabled');
3678
+ const base = DtoGroup(policy.modelLike, [...policy.groups], policy.aggrs);
3679
+ return $Class.partial(base);
3680
+ }
3681
+ function DtoAnalysisAggregate(policy) {
3682
+ if (!policy.defaults.aggregate) throw new TypeError('Analysis aggregate action is not enabled');
3683
+ class TargetClass {}
3684
+ // Aggregate aliases deliberately do not copy field validators/renderers from source columns.
3685
+ return _DtoAggregate_inner(TargetClass, policy.modelLike, policy.aggrs);
3686
+ }
3687
+
3380
3688
  function DtoGet(modelLike, params) {
3381
3689
  return _DtoGet_raw(modelLike, params);
3382
3690
  }
@@ -3623,6 +3931,8 @@ const $Dto = {
3623
3931
  mutate: DtoMutate,
3624
3932
  get: DtoGet,
3625
3933
  aggregate: DtoAggregate,
3934
+ analysisGroup: DtoAnalysisGroup,
3935
+ analysisAggregate: DtoAnalysisAggregate,
3626
3936
  group: DtoGroup,
3627
3937
  query: DtoQuery,
3628
3938
  queryPage: DtoQueryPage,
@@ -3997,7 +4307,7 @@ class BeanModelCache extends BeanModelCrud {
3997
4307
  },
3998
4308
  db: this.db
3999
4309
  });
4000
- return items;
4310
+ return normalizeAggregateRows(items, params?.aggrs);
4001
4311
  }
4002
4312
  async get(where, options) {
4003
4313
  const relations = this.relations.handleRelationsCollection(options);
@@ -4623,5 +4933,5 @@ const $relationMutate = {
4623
4933
  belongsToMany
4624
4934
  };
4625
4935
 
4626
- export { $Dto, $locale, $relation, $relationDynamic, $relationMutate, AopMethodTransaction, BeanDatabase, BeanModel, BeanModelBase, BeanModelMeta, BroadcastColumnsClear, DatabaseDialect, DtoQueryBase, DtoQueryPageBase, Entity, EntityBase, EntityBaseEmpty, EntityBaseInner, EntityBaseSimple, EventClientNameReal, EventColumnsClear, ExtendKnex, ExtendSchemaBuilder, ExtendTableBuilder, HmrEntity, HmrModel, Main, Model, Op, OpAggrs, OpJoint, OpJointValues, OpNormal, OpNormalValues, OpValues, QueueDoubleDelete, ScheduleSoftDeletionPrune, ScopeModuleAOrm, ServiceCacheEntity, ServiceCacheQuery, ServiceColumns, ServiceColumnsCache, ServiceDatabase, ServiceDatabaseAsyncLocalStorage, ServiceDatabaseClient, ServiceDatabaseDialectBase, ServiceDb, ServiceEntityResolver, ServiceModelResolver, ServiceRelations, ServiceTransaction, ServiceTransactionAsyncLocalStorage, ServiceTransactionConsistency‌, ServiceTransactionFiber, ServiceTransactionState, SymbolCacheModelCacheInstances, SymbolCacheModelsClear, SymbolKeyEntity, SymbolKeyEntityMeta, SymbolKeyFieldsMore, SymbolKeyModelOptions, TransactionIsolationLevelsMap, buildWhere, clearAllCacheModelsClear, clearCacheModelCacheInstance, config, configDefault, errors, getCacheModelCacheInstances, getCacheModelsClear, getClassEntityFromClassModel, getTableOrTableAlias, getTargetColumnName, isRaw, isRef, locales, prepareClassModel, prepareColumns };
4936
+ export { $Dto, $defineAnalysis, $executeAnalysisAggregate, $executeAnalysisGroup, $locale, $relation, $relationDynamic, $relationMutate, AnalysisError, AopMethodTransaction, BeanDatabase, BeanModel, BeanModelBase, BeanModelMeta, BroadcastColumnsClear, DatabaseDialect, DtoQueryBase, DtoQueryPageBase, Entity, EntityBase, EntityBaseEmpty, EntityBaseInner, EntityBaseSimple, EventClientNameReal, EventColumnsClear, ExtendKnex, ExtendSchemaBuilder, ExtendTableBuilder, HmrEntity, HmrModel, Main, Model, Op, OpAggrs, OpJoint, OpJointValues, OpNormal, OpNormalValues, OpValues, QueueDoubleDelete, ScheduleSoftDeletionPrune, ScopeModuleAOrm, ServiceCacheEntity, ServiceCacheQuery, ServiceColumns, ServiceColumnsCache, ServiceDatabase, ServiceDatabaseAsyncLocalStorage, ServiceDatabaseClient, ServiceDatabaseDialectBase, ServiceDb, ServiceEntityResolver, ServiceModelResolver, ServiceRelations, ServiceTransaction, ServiceTransactionAsyncLocalStorage, ServiceTransactionConsistency‌, ServiceTransactionFiber, ServiceTransactionState, SymbolCacheModelCacheInstances, SymbolCacheModelsClear, SymbolKeyEntity, SymbolKeyEntityMeta, SymbolKeyFieldsMore, SymbolKeyModelOptions, TransactionIsolationLevelsMap, analysisCapabilities, analysisControlSchemas, analysisFailure, analysisFunctions, analysisReservedFields, buildWhere, clearAllCacheModelsClear, clearCacheModelCacheInstance, config, configDefault, errors, getCacheModelCacheInstances, getCacheModelsClear, getClassEntityFromClassModel, getTableOrTableAlias, getTargetColumnName, isRaw, isRef, locales, prepareClassModel, prepareColumns, resolveAnalysis };
4627
4937
  //# sourceMappingURL=index.js.map