@fiado/type-kit 3.572.0 → 3.573.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.
@@ -56,3 +56,25 @@ describe('population DTOs', () => {
56
56
  expect(Object.keys(Rules.PopulationExecutionStatusEnum)).toEqual(['RUNNING', 'SUCCEEDED', 'FAILED', 'CANCELLED']);
57
57
  });
58
58
  });
59
+
60
+ describe('rutas de columna (SEGMENT_COLUMN_PATH_PATTERN)', () => {
61
+ const colCond = (column: string) => ({ kind: 'COLUMN', table: 'riskprofile', column, op: 'GT', value: 1 });
62
+ it.each(['score', 'riskfactors.income.value', 'a.b.c.d.e.f.g.h'])('column "%s" válida -> 0 errores', async (column) => {
63
+ expect(await errorsOf(Rules.SegmentColumnCondition, colCond(column))).toBe(0);
64
+ });
65
+ it.each(['a.b.c.d.e.f.g.h.i', 'Riskfactors.income', 'a..b', 'a.', '.a', 'a.1b', 'a-b.c'])('column "%s" inválida -> error', async (column) => {
66
+ expect(await errorsOf(Rules.SegmentColumnCondition, colCond(column))).toBeGreaterThan(0);
67
+ });
68
+ it('table con punto sigue inválida', async () => {
69
+ expect(await errorsOf(Rules.SegmentColumnCondition, { ...colCond('score'), table: 'a.b' })).toBeGreaterThan(0);
70
+ });
71
+ it('dateColumn anidada válida y SEGMENT_MAX_PATH_DEPTH = 8', async () => {
72
+ expect(await errorsOf(Rules.SegmentWindow, { dateColumn: 'riskfactors.income.evaluationat', days: 30 })).toBe(0);
73
+ expect(Rules.SEGMENT_MAX_PATH_DEPTH).toBe(8);
74
+ });
75
+ it('aggregate column anidada válida', async () => {
76
+ const agg = { kind: 'AGGREGATE', table: 'tx', fn: 'SUM', column: 'a.b.c', op: 'GT', value: 1 };
77
+ const errs = await validate(plainToInstance(Rules.SegmentAggregateCondition, agg, { excludeExtraneousValues: true }));
78
+ expect(errs.filter((e) => e.property === 'column')).toHaveLength(0);
79
+ });
80
+ });
@@ -1,5 +1,8 @@
1
1
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
2
  export declare const SEGMENT_IDENTIFIER_PATTERN: RegExp;
3
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
4
+ export declare const SEGMENT_COLUMN_PATH_PATTERN: RegExp;
5
+ export declare const SEGMENT_MAX_PATH_DEPTH = 8;
3
6
  export declare const SEGMENT_MAX_DAYS = 365;
4
7
  export declare const SEGMENT_MAX_PARAMS = 40;
5
8
  export declare const SEGMENT_MAX_AGGREGATES = 8;
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SEGMENT_MAX_AGGREGATES = exports.SEGMENT_MAX_PARAMS = exports.SEGMENT_MAX_DAYS = exports.SEGMENT_IDENTIFIER_PATTERN = void 0;
3
+ exports.SEGMENT_MAX_AGGREGATES = exports.SEGMENT_MAX_PARAMS = exports.SEGMENT_MAX_DAYS = exports.SEGMENT_MAX_PATH_DEPTH = exports.SEGMENT_COLUMN_PATH_PATTERN = exports.SEGMENT_IDENTIFIER_PATTERN = void 0;
4
4
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
5
5
  exports.SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
6
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
7
+ exports.SEGMENT_COLUMN_PATH_PATTERN = /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*){0,7}$/;
8
+ exports.SEGMENT_MAX_PATH_DEPTH = 8;
6
9
  exports.SEGMENT_MAX_DAYS = 365;
7
10
  exports.SEGMENT_MAX_PARAMS = 40;
8
11
  exports.SEGMENT_MAX_AGGREGATES = 8;
@@ -40,7 +40,7 @@ __decorate([
40
40
  __decorate([
41
41
  (0, class_transformer_1.Expose)(),
42
42
  (0, class_validator_1.IsOptional)(),
43
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
43
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
44
44
  __metadata("design:type", String)
45
45
  ], SegmentAggregateCondition.prototype, "column", void 0);
46
46
  __decorate([
@@ -31,7 +31,7 @@ __decorate([
31
31
  ], SegmentColumnCondition.prototype, "table", void 0);
32
32
  __decorate([
33
33
  (0, class_transformer_1.Expose)(),
34
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
34
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
35
35
  __metadata("design:type", String)
36
36
  ], SegmentColumnCondition.prototype, "column", void 0);
37
37
  __decorate([
@@ -1,6 +1,8 @@
1
1
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
2
2
  export declare class SegmentColumnSchemaResponse {
3
3
  name: string;
4
+ /** Columna raiz de Glue cuando `name` es una ruta a una hoja de struct (agrupa en la UI). */
5
+ root?: string;
4
6
  type: string;
5
7
  isDate: boolean;
6
8
  operators: SegmentOperatorEnum[];
@@ -19,7 +19,7 @@ class SegmentWindow {
19
19
  exports.SegmentWindow = SegmentWindow;
20
20
  __decorate([
21
21
  (0, class_transformer_1.Expose)(),
22
- (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_IDENTIFIER_PATTERN),
22
+ (0, class_validator_1.Matches)(SegmentLimits_1.SEGMENT_COLUMN_PATH_PATTERN),
23
23
  __metadata("design:type", String)
24
24
  ], SegmentWindow.prototype, "dateColumn", void 0);
25
25
  __decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.572.0",
3
+ "version": "3.573.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
@@ -1,5 +1,8 @@
1
1
  /** Identificador SQL permitido para tabla/columna (A§4.3 paso 1): minusculas, digitos y guion bajo; nunca texto libre. */
2
2
  export const SEGMENT_IDENTIFIER_PATTERN = /^[a-z_][a-z0-9_]*$/;
3
+ /** Ruta a una hoja de columna struct de Glue (`riskfactors.income.value`): segmentos separados por punto, maximo SEGMENT_MAX_PATH_DEPTH. Una columna plana es una ruta de 1 segmento. */
4
+ export const SEGMENT_COLUMN_PATH_PATTERN = /^[a-z_][a-z0-9_]*(\.[a-z_][a-z0-9_]*){0,7}$/;
5
+ export const SEGMENT_MAX_PATH_DEPTH = 8;
3
6
  export const SEGMENT_MAX_DAYS = 365;
4
7
  export const SEGMENT_MAX_PARAMS = 40;
5
8
  export const SEGMENT_MAX_AGGREGATES = 8;
@@ -1,6 +1,6 @@
1
1
  import { Expose, Type } from 'class-transformer';
2
2
  import { ArrayMaxSize, Equals, IsArray, IsEnum, IsNumber, IsOptional, Matches, ValidateNested } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
3
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
4
4
  import { SegmentAggregateFnEnum } from '../../enums/SegmentAggregateFnEnum';
5
5
  import { SegmentConditionKindEnum } from '../../enums/SegmentConditionKindEnum';
6
6
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
@@ -13,7 +13,7 @@ export class SegmentAggregateCondition {
13
13
  @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
14
14
  @Expose() @IsEnum(SegmentAggregateFnEnum) fn: SegmentAggregateFnEnum;
15
15
  /** Solo SUM. */
16
- @Expose() @IsOptional() @Matches(SEGMENT_IDENTIFIER_PATTERN) column?: string;
16
+ @Expose() @IsOptional() @Matches(SEGMENT_COLUMN_PATH_PATTERN) column?: string;
17
17
  /** COUNT y SUM; EXISTS no lleva. */
18
18
  @Expose() @IsOptional() @IsEnum(SegmentOperatorEnum) op?: SegmentOperatorEnum;
19
19
  @Expose() @IsOptional() @IsNumber() value?: number;
@@ -1,7 +1,7 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { Equals, IsEnum, IsOptional, Matches } from 'class-validator';
3
3
  import { JsonValue } from '../../../common';
4
- import { SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
4
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_IDENTIFIER_PATTERN } from '../../constants/SegmentLimits';
5
5
  import { SegmentConditionKindEnum } from '../../enums/SegmentConditionKindEnum';
6
6
  import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
7
7
 
@@ -9,7 +9,7 @@ import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
9
9
  export class SegmentColumnCondition {
10
10
  @Expose() @Equals(SegmentConditionKindEnum.COLUMN) kind: SegmentConditionKindEnum.COLUMN;
11
11
  @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) table: string;
12
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) column: string;
12
+ @Expose() @Matches(SEGMENT_COLUMN_PATH_PATTERN) column: string;
13
13
  @Expose() @IsEnum(SegmentOperatorEnum) op: SegmentOperatorEnum;
14
14
  @Expose() @IsOptional() value?: JsonValue;
15
15
  }
@@ -2,6 +2,8 @@ import { SegmentOperatorEnum } from '../../enums/SegmentOperatorEnum';
2
2
 
3
3
  export class SegmentColumnSchemaResponse {
4
4
  name: string;
5
+ /** Columna raiz de Glue cuando `name` es una ruta a una hoja de struct (agrupa en la UI). */
6
+ root?: string;
5
7
  type: string;
6
8
  isDate: boolean;
7
9
  operators: SegmentOperatorEnum[];
@@ -1,9 +1,9 @@
1
1
  import { Expose } from 'class-transformer';
2
2
  import { IsInt, Matches, Max, Min } from 'class-validator';
3
- import { SEGMENT_IDENTIFIER_PATTERN, SEGMENT_MAX_DAYS } from '../../constants/SegmentLimits';
3
+ import { SEGMENT_COLUMN_PATH_PATTERN, SEGMENT_MAX_DAYS } from '../../constants/SegmentLimits';
4
4
 
5
5
  /** Ventana relativa [referenceAt - days, referenceAt) sobre una columna de fecha (A§4.1). */
6
6
  export class SegmentWindow {
7
- @Expose() @Matches(SEGMENT_IDENTIFIER_PATTERN) dateColumn: string;
7
+ @Expose() @Matches(SEGMENT_COLUMN_PATH_PATTERN) dateColumn: string;
8
8
  @Expose() @IsInt() @Min(1) @Max(SEGMENT_MAX_DAYS) days: number;
9
9
  }