@fiado/type-kit 3.399.0 → 3.400.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.
@@ -0,0 +1,83 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { validate, ValidationError } from 'class-validator';
4
+ import { DeviceEnrollRequest } from '../../../../src/mdm/dtos/DeviceEnrollRequest';
5
+ import { DeviceUnlockRequest } from '../../../../src/mdm/dtos/DeviceUnlockRequest';
6
+ import { MdmErrorCodeEnum } from '../../../../src/mdm/enums/MdmErrorCodeEnum';
7
+ import * as MdmBarrel from '../../../../src/mdm/index';
8
+ import { MdmLockModeEnum } from '../../../../src/retailCatalog/enums/MdmLockModeEnum';
9
+
10
+ /** ULID real del motor: así genera los creditId `loan-credit-business`. */
11
+ const CREDIT_ID = '01M0B5D7FQA3T06K4REEVPRM33';
12
+
13
+ /** True si el error de `property` trae ese constraint puntual (no solo "algo falló"). */
14
+ const hasConstraint = (errors: ValidationError[], property: string, constraint: string): boolean =>
15
+ errors.some(e => e.property === property && Boolean(e.constraints?.[constraint]));
16
+
17
+ /** Payload de enrolamiento tal como lo manda hoy un consumidor ya desplegado. */
18
+ const validEnroll = {
19
+ imei: '351756051523999',
20
+ creditId: CREDIT_ID,
21
+ termMonths: 6,
22
+ operationReference: 'enroll-2026-09-01-0001',
23
+ };
24
+
25
+ const validUnlock = {
26
+ imei: '351756051523999',
27
+ operationReference: 'unlock-2026-09-01-0001',
28
+ };
29
+
30
+ describe('DeviceEnrollRequest.lockMode', () => {
31
+ it('valida sin lockMode: el consumidor de hoy no se rompe', async () => {
32
+ const dto = plainToInstance(DeviceEnrollRequest, validEnroll);
33
+ const errors = await validate(dto);
34
+ expect(errors).toEqual([]);
35
+ expect(dto.lockMode).toBeUndefined();
36
+ });
37
+
38
+ it.each([MdmLockModeEnum.ONDEMAND, MdmLockModeEnum.SCHEDULED])('valida con lockMode %s', async lockMode => {
39
+ const dto = plainToInstance(DeviceEnrollRequest, { ...validEnroll, lockMode });
40
+ const errors = await validate(dto);
41
+ expect(errors).toEqual([]);
42
+ expect(dto.lockMode).toBe(lockMode);
43
+ });
44
+
45
+ it('falla si lockMode está fuera del enum', async () => {
46
+ const dto = plainToInstance(DeviceEnrollRequest, { ...validEnroll, lockMode: 'PREPAGO' });
47
+ const errors = await validate(dto);
48
+ expect(hasConstraint(errors, 'lockMode', 'isEnum')).toBe(true);
49
+ });
50
+ });
51
+
52
+ describe('DeviceUnlockRequest.unlockUntil', () => {
53
+ it('valida sin unlockUntil: el consumidor de hoy no se rompe', async () => {
54
+ const dto = plainToInstance(DeviceUnlockRequest, validUnlock);
55
+ const errors = await validate(dto);
56
+ expect(errors).toEqual([]);
57
+ expect(dto.unlockUntil).toBeUndefined();
58
+ });
59
+
60
+ it('valida con unlockUntil en ISO-8601', async () => {
61
+ const dto = plainToInstance(DeviceUnlockRequest, { ...validUnlock, unlockUntil: '2026-10-01T00:00:00.000Z' });
62
+ const errors = await validate(dto);
63
+ expect(errors).toEqual([]);
64
+ });
65
+
66
+ it('falla si unlockUntil no es ISO-8601', async () => {
67
+ const dto = plainToInstance(DeviceUnlockRequest, { ...validUnlock, unlockUntil: '01/10/2026' });
68
+ const errors = await validate(dto);
69
+ expect(hasConstraint(errors, 'unlockUntil', 'isIso8601')).toBe(true);
70
+ });
71
+ });
72
+
73
+ describe('MdmErrorCodeEnum', () => {
74
+ it('expone el código de desbloqueo sin vigencia sobre un equipo SCHEDULED', () => {
75
+ expect(MdmErrorCodeEnum.UNLOCK_UNTIL_REQUIRED).toBe('UNLOCK_UNTIL_REQUIRED');
76
+ });
77
+ });
78
+
79
+ describe('barrel de mdm', () => {
80
+ it('reexporta MdmLockModeEnum sin duplicar el enum de retailCatalog', () => {
81
+ expect(MdmBarrel.MdmLockModeEnum).toBe(MdmLockModeEnum);
82
+ });
83
+ });
@@ -1,3 +1,4 @@
1
+ import { MdmLockModeEnum } from "../../retailCatalog/enums/MdmLockModeEnum";
1
2
  export declare class DeviceEnrollRequest {
2
3
  imei: string;
3
4
  imei2?: string;
@@ -5,5 +6,7 @@ export declare class DeviceEnrollRequest {
5
6
  model?: string;
6
7
  creditId: string;
7
8
  termMonths: number;
9
+ /** Cuándo se dispara el bloqueo del equipo; si se omite es ONDEMAND, que es el modo de hoy. */
10
+ lockMode?: MdmLockModeEnum;
8
11
  operationReference: string;
9
12
  }
@@ -13,6 +13,7 @@ exports.DeviceEnrollRequest = void 0;
13
13
  const class_transformer_1 = require("class-transformer");
14
14
  const class_validator_1 = require("class-validator");
15
15
  const CreditIdPattern_1 = require("../../common/constants/CreditIdPattern");
16
+ const MdmLockModeEnum_1 = require("../../retailCatalog/enums/MdmLockModeEnum");
16
17
  class DeviceEnrollRequest {
17
18
  }
18
19
  exports.DeviceEnrollRequest = DeviceEnrollRequest;
@@ -51,6 +52,12 @@ __decorate([
51
52
  (0, class_validator_1.IsPositive)(),
52
53
  __metadata("design:type", Number)
53
54
  ], DeviceEnrollRequest.prototype, "termMonths", void 0);
55
+ __decorate([
56
+ (0, class_transformer_1.Expose)(),
57
+ (0, class_validator_1.IsEnum)(MdmLockModeEnum_1.MdmLockModeEnum),
58
+ (0, class_validator_1.IsOptional)(),
59
+ __metadata("design:type", String)
60
+ ], DeviceEnrollRequest.prototype, "lockMode", void 0);
54
61
  __decorate([
55
62
  (0, class_transformer_1.Expose)(),
56
63
  (0, class_validator_1.IsString)(),
@@ -1,4 +1,6 @@
1
1
  export declare class DeviceUnlockRequest {
2
2
  imei: string;
3
+ /** ISO-8601 de hasta cuándo vale el desbloqueo; solo aplica en modo SCHEDULED. */
4
+ unlockUntil?: string;
3
5
  operationReference: string;
4
6
  }
@@ -21,6 +21,12 @@ __decorate([
21
21
  (0, class_validator_1.IsNotEmpty)(),
22
22
  __metadata("design:type", String)
23
23
  ], DeviceUnlockRequest.prototype, "imei", void 0);
24
+ __decorate([
25
+ (0, class_transformer_1.Expose)(),
26
+ (0, class_validator_1.IsISO8601)(),
27
+ (0, class_validator_1.IsOptional)(),
28
+ __metadata("design:type", String)
29
+ ], DeviceUnlockRequest.prototype, "unlockUntil", void 0);
24
30
  __decorate([
25
31
  (0, class_transformer_1.Expose)(),
26
32
  (0, class_validator_1.IsString)(),
@@ -3,6 +3,7 @@ export declare enum MdmErrorCodeEnum {
3
3
  DEVICE_NOT_FOUND = "DEVICE_NOT_FOUND",
4
4
  DEVICE_NOT_ENROLLED = "DEVICE_NOT_ENROLLED",
5
5
  INVALID_REQUEST = "INVALID_REQUEST",
6
+ UNLOCK_UNTIL_REQUIRED = "UNLOCK_UNTIL_REQUIRED",
6
7
  PROVIDER_ERROR = "PROVIDER_ERROR",
7
8
  PROVIDER_TIMEOUT = "PROVIDER_TIMEOUT",
8
9
  PROVIDER_RATE_LIMITED = "PROVIDER_RATE_LIMITED",
@@ -7,6 +7,7 @@ var MdmErrorCodeEnum;
7
7
  MdmErrorCodeEnum["DEVICE_NOT_FOUND"] = "DEVICE_NOT_FOUND";
8
8
  MdmErrorCodeEnum["DEVICE_NOT_ENROLLED"] = "DEVICE_NOT_ENROLLED";
9
9
  MdmErrorCodeEnum["INVALID_REQUEST"] = "INVALID_REQUEST";
10
+ MdmErrorCodeEnum["UNLOCK_UNTIL_REQUIRED"] = "UNLOCK_UNTIL_REQUIRED";
10
11
  MdmErrorCodeEnum["PROVIDER_ERROR"] = "PROVIDER_ERROR";
11
12
  MdmErrorCodeEnum["PROVIDER_TIMEOUT"] = "PROVIDER_TIMEOUT";
12
13
  MdmErrorCodeEnum["PROVIDER_RATE_LIMITED"] = "PROVIDER_RATE_LIMITED";
@@ -45,3 +45,4 @@ export * from "./enums/MdmOperationStatusEnum";
45
45
  export * from "./enums/MdmErrorCodeEnum";
46
46
  export * from "./enums/MdmProviderEnum";
47
47
  export * from "./enums/MdmOperationTypeEnum";
48
+ export { MdmLockModeEnum } from "../retailCatalog/enums/MdmLockModeEnum";
package/bin/mdm/index.js CHANGED
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MdmLockModeEnum = void 0;
17
18
  // dtos
18
19
  __exportStar(require("./dtos/MdmError"), exports);
19
20
  __exportStar(require("./dtos/DeviceLockScreenMessage"), exports);
@@ -68,3 +69,6 @@ __exportStar(require("./enums/MdmOperationStatusEnum"), exports);
68
69
  __exportStar(require("./enums/MdmErrorCodeEnum"), exports);
69
70
  __exportStar(require("./enums/MdmProviderEnum"), exports);
70
71
  __exportStar(require("./enums/MdmOperationTypeEnum"), exports);
72
+ // enums de otro dominio — el modo de bloqueo lo define el producto en el catálogo
73
+ var MdmLockModeEnum_1 = require("../retailCatalog/enums/MdmLockModeEnum");
74
+ Object.defineProperty(exports, "MdmLockModeEnum", { enumerable: true, get: function () { return MdmLockModeEnum_1.MdmLockModeEnum; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiado/type-kit",
3
- "version": "3.399.0",
3
+ "version": "3.400.0",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",
package/src/mdm/README.md CHANGED
@@ -60,6 +60,22 @@ import { Mdm } from "@fiado/type-kit";
60
60
  | DeviceLastSeen | (incluido en Device Info) | Device Last Seen |
61
61
  | DeviceLog | ❌ Error: no expone | Device Log |
62
62
 
63
+ ## Modo de bloqueo (`MdmLockModeEnum`)
64
+
65
+ El enum lo define el catálogo (`retailCatalog`), porque el modo es un atributo del producto que se
66
+ congela al enrolar. El dominio `mdm` lo reexporta para no duplicarlo.
67
+
68
+ | Modo | Qué significa | Cómo se comporta |
69
+ |---|---|---|
70
+ | `ONDEMAND` | El bloqueo se dispara bajo demanda | Solo se bloquea cuando se lo ordenan |
71
+ | `SCHEDULED` | El bloqueo se dispara de forma programada | Se bloquea al vencer la vigencia; cada pago la corre |
72
+
73
+ - `DeviceEnrollRequest.lockMode` — opcional; ausente equivale a `ONDEMAND`.
74
+ - `DeviceUnlockRequest.unlockUntil` — opcional; ISO-8601 de hasta cuándo vale el desbloqueo. En
75
+ `ONDEMAND` no aplica y se ignora.
76
+ - `MdmErrorCodeEnum.UNLOCK_UNTIL_REQUIRED` — un desbloqueo sin `unlockUntil` sobre un equipo
77
+ `SCHEDULED` se rechaza: mandarlo sin vigencia liberaría el equipo sin fecha de re-bloqueo.
78
+
63
79
  ## Eventos entrantes (solo Datacultr)
64
80
 
65
81
  - `DeviceEnrollmentCompletedEvent` — Enrollment Webhook
@@ -1,6 +1,7 @@
1
1
  import { Expose } from "class-transformer";
2
- import { IsString, IsNotEmpty, IsOptional, IsNumber, IsPositive, Matches } from "class-validator";
2
+ import { IsString, IsNotEmpty, IsOptional, IsNumber, IsPositive, Matches, IsEnum } from "class-validator";
3
3
  import { CREDIT_ID_MESSAGE, CREDIT_ID_PATTERN } from "../../common/constants/CreditIdPattern";
4
+ import { MdmLockModeEnum } from "../../retailCatalog/enums/MdmLockModeEnum";
4
5
 
5
6
  export class DeviceEnrollRequest {
6
7
  @Expose()
@@ -32,6 +33,12 @@ export class DeviceEnrollRequest {
32
33
  @IsPositive()
33
34
  termMonths: number;
34
35
 
36
+ /** Cuándo se dispara el bloqueo del equipo; si se omite es ONDEMAND, que es el modo de hoy. */
37
+ @Expose()
38
+ @IsEnum(MdmLockModeEnum)
39
+ @IsOptional()
40
+ lockMode?: MdmLockModeEnum;
41
+
35
42
  @Expose()
36
43
  @IsString()
37
44
  @IsNotEmpty()
@@ -1,5 +1,5 @@
1
1
  import { Expose } from "class-transformer";
2
- import { IsString, IsNotEmpty } from "class-validator";
2
+ import { IsString, IsNotEmpty, IsOptional, IsISO8601 } from "class-validator";
3
3
 
4
4
  export class DeviceUnlockRequest {
5
5
  @Expose()
@@ -7,6 +7,12 @@ export class DeviceUnlockRequest {
7
7
  @IsNotEmpty()
8
8
  imei: string;
9
9
 
10
+ /** ISO-8601 de hasta cuándo vale el desbloqueo; solo aplica en modo SCHEDULED. */
11
+ @Expose()
12
+ @IsISO8601()
13
+ @IsOptional()
14
+ unlockUntil?: string;
15
+
10
16
  @Expose()
11
17
  @IsString()
12
18
  @IsNotEmpty()
@@ -3,6 +3,7 @@ export enum MdmErrorCodeEnum {
3
3
  DEVICE_NOT_FOUND = "DEVICE_NOT_FOUND",
4
4
  DEVICE_NOT_ENROLLED = "DEVICE_NOT_ENROLLED",
5
5
  INVALID_REQUEST = "INVALID_REQUEST",
6
+ UNLOCK_UNTIL_REQUIRED = "UNLOCK_UNTIL_REQUIRED",
6
7
  PROVIDER_ERROR = "PROVIDER_ERROR",
7
8
  PROVIDER_TIMEOUT = "PROVIDER_TIMEOUT",
8
9
  PROVIDER_RATE_LIMITED = "PROVIDER_RATE_LIMITED",
package/src/mdm/index.ts CHANGED
@@ -58,3 +58,6 @@ export * from "./enums/MdmOperationStatusEnum";
58
58
  export * from "./enums/MdmErrorCodeEnum";
59
59
  export * from "./enums/MdmProviderEnum";
60
60
  export * from "./enums/MdmOperationTypeEnum";
61
+
62
+ // enums de otro dominio — el modo de bloqueo lo define el producto en el catálogo
63
+ export { MdmLockModeEnum } from "../retailCatalog/enums/MdmLockModeEnum";