@dismissible/nestjs-validation 0.0.2-canary.c91edbc.0 → 0.0.2-canary.d2f56d7.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/jest.config.ts CHANGED
@@ -7,4 +7,21 @@ export default {
7
7
  },
8
8
  moduleFileExtensions: ['ts', 'js', 'html'],
9
9
  coverageDirectory: '../../coverage/libs/validation',
10
+ collectCoverageFrom: [
11
+ 'src/**/*.ts',
12
+ '!src/**/*.spec.ts',
13
+ '!src/**/*.interface.ts',
14
+ '!src/**/*.dto.ts',
15
+ '!src/**/*.enum.ts',
16
+ '!src/**/index.ts',
17
+ '!src/**/*.module.ts',
18
+ ],
19
+ coverageThreshold: {
20
+ global: {
21
+ branches: 80,
22
+ functions: 80,
23
+ lines: 80,
24
+ statements: 80,
25
+ },
26
+ },
10
27
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dismissible/nestjs-validation",
3
- "version": "0.0.2-canary.c91edbc.0",
3
+ "version": "0.0.2-canary.d2f56d7.0",
4
4
  "description": "Validation service module for NestJS applications using class-validator and class-transformer",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/index.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './validation.service';
2
2
  export * from './validation.module';
3
+ export * from './transform-boolean.decorator';
4
+ export * from './transform-comma-separated.decorator';
@@ -0,0 +1,102 @@
1
+ import 'reflect-metadata';
2
+ import { IsBoolean } from 'class-validator';
3
+ import { plainToInstance } from 'class-transformer';
4
+ import { TransformBoolean } from './transform-boolean.decorator';
5
+
6
+ class TestConfig {
7
+ @IsBoolean()
8
+ @TransformBoolean()
9
+ value!: boolean;
10
+ }
11
+
12
+ class TestConfigWithDefault {
13
+ @IsBoolean()
14
+ @TransformBoolean(true)
15
+ value!: boolean;
16
+ }
17
+
18
+ describe('TransformBoolean', () => {
19
+ describe('without default value', () => {
20
+ it('should transform string "true" to boolean true', () => {
21
+ const config = plainToInstance(TestConfig, { value: 'true' });
22
+ expect(config.value).toBe(true);
23
+ });
24
+
25
+ it('should transform string "false" to boolean false', () => {
26
+ const config = plainToInstance(TestConfig, { value: 'false' });
27
+ expect(config.value).toBe(false);
28
+ });
29
+
30
+ it('should keep boolean true as true', () => {
31
+ const config = plainToInstance(TestConfig, { value: true });
32
+ expect(config.value).toBe(true);
33
+ });
34
+
35
+ it('should keep boolean false as false', () => {
36
+ const config = plainToInstance(TestConfig, { value: false });
37
+ expect(config.value).toBe(false);
38
+ });
39
+
40
+ it('should transform other string values to false', () => {
41
+ const config = plainToInstance(TestConfig, { value: 'yes' });
42
+ expect(config.value).toBe(false);
43
+ });
44
+
45
+ it('should handle case-insensitive "true"', () => {
46
+ const config = plainToInstance(TestConfig, { value: 'TRUE' });
47
+ expect(config.value).toBe(true);
48
+ });
49
+
50
+ it('should handle case-insensitive "True"', () => {
51
+ const config = plainToInstance(TestConfig, { value: 'True' });
52
+ expect(config.value).toBe(true);
53
+ });
54
+
55
+ it('should preserve undefined when no default provided', () => {
56
+ const config = plainToInstance(TestConfig, { value: undefined });
57
+ expect(config.value).toBeUndefined();
58
+ });
59
+
60
+ it('should preserve null when no default provided', () => {
61
+ const config = plainToInstance(TestConfig, { value: null });
62
+ expect(config.value).toBeNull();
63
+ });
64
+
65
+ it('should preserve other types when no default provided', () => {
66
+ const config = plainToInstance(TestConfig, { value: 123 });
67
+ expect(config.value).toBe(123);
68
+ });
69
+ });
70
+
71
+ describe('with default value', () => {
72
+ it('should use default value for undefined', () => {
73
+ const config = plainToInstance(TestConfigWithDefault, { value: undefined });
74
+ expect(config.value).toBe(true);
75
+ });
76
+
77
+ it('should use default value for null', () => {
78
+ const config = plainToInstance(TestConfigWithDefault, { value: null });
79
+ expect(config.value).toBe(true);
80
+ });
81
+
82
+ it('should use default value for other types', () => {
83
+ const config = plainToInstance(TestConfigWithDefault, { value: 123 });
84
+ expect(config.value).toBe(true);
85
+ });
86
+
87
+ it('should still transform string "true" to boolean true', () => {
88
+ const config = plainToInstance(TestConfigWithDefault, { value: 'true' });
89
+ expect(config.value).toBe(true);
90
+ });
91
+
92
+ it('should still transform string "false" to boolean false', () => {
93
+ const config = plainToInstance(TestConfigWithDefault, { value: 'false' });
94
+ expect(config.value).toBe(false);
95
+ });
96
+
97
+ it('should still keep boolean true as true', () => {
98
+ const config = plainToInstance(TestConfigWithDefault, { value: true });
99
+ expect(config.value).toBe(true);
100
+ });
101
+ });
102
+ });
@@ -0,0 +1,29 @@
1
+ import { Transform } from 'class-transformer';
2
+
3
+ /**
4
+ * Transforms string values to boolean, preserving existing boolean values.
5
+ * Useful for environment variable configuration where boolean values may be passed as strings.
6
+ *
7
+ * @param defaultValue - Optional default value to return if the value is not a boolean or string.
8
+ * If not provided, the original value is returned unchanged.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * class Config {
13
+ * @IsBoolean()
14
+ * @TransformBoolean()
15
+ * enabled!: boolean;
16
+ * }
17
+ * ```
18
+ */
19
+ export function TransformBoolean(defaultValue?: boolean): PropertyDecorator {
20
+ return Transform(({ value }) => {
21
+ if (typeof value === 'boolean') {
22
+ return value;
23
+ }
24
+ if (typeof value === 'string') {
25
+ return value.toLowerCase() === 'true';
26
+ }
27
+ return defaultValue !== undefined ? defaultValue : value;
28
+ });
29
+ }
@@ -0,0 +1,40 @@
1
+ import 'reflect-metadata';
2
+ import { plainToInstance } from 'class-transformer';
3
+ import { TransformCommaSeparated } from './transform-comma-separated.decorator';
4
+
5
+ class TestConfig {
6
+ @TransformCommaSeparated()
7
+ value!: string[] | string;
8
+ }
9
+
10
+ describe('TransformCommaSeparated', () => {
11
+ it('should transform comma-separated string into array of trimmed strings', () => {
12
+ const config = plainToInstance(TestConfig, { value: 'GET,POST,DELETE' });
13
+ expect(config.value).toEqual(['GET', 'POST', 'DELETE']);
14
+ });
15
+
16
+ it('should trim whitespace from each element', () => {
17
+ const config = plainToInstance(TestConfig, { value: 'a , b , c' });
18
+ expect(config.value).toEqual(['a', 'b', 'c']);
19
+ });
20
+
21
+ it('should handle single value string', () => {
22
+ const config = plainToInstance(TestConfig, { value: 'GET' });
23
+ expect(config.value).toEqual(['GET']);
24
+ });
25
+
26
+ it('should return array as-is when value is already an array', () => {
27
+ const config = plainToInstance(TestConfig, { value: ['a', 'b'] });
28
+ expect(config.value).toEqual(['a', 'b']);
29
+ });
30
+
31
+ it('should handle empty string', () => {
32
+ const config = plainToInstance(TestConfig, { value: '' });
33
+ expect(config.value).toEqual(['']);
34
+ });
35
+
36
+ it('should handle string with only whitespace', () => {
37
+ const config = plainToInstance(TestConfig, { value: ' ' });
38
+ expect(config.value).toEqual(['']);
39
+ });
40
+ });
@@ -0,0 +1,16 @@
1
+ import { Transform } from 'class-transformer';
2
+
3
+ /**
4
+ * Transforms a comma-separated string into an array of trimmed strings.
5
+ * If the value is already an array, it is returned as-is.
6
+ *
7
+ * @example
8
+ * // Input: "GET,POST,DELETE" → Output: ["GET", "POST", "DELETE"]
9
+ * // Input: "a , b , c" → Output: ["a", "b", "c"]
10
+ * // Input: ["a", "b"] → Output: ["a", "b"]
11
+ */
12
+ export function TransformCommaSeparated(): PropertyDecorator {
13
+ return Transform(({ value }) =>
14
+ typeof value === 'string' ? value.split(',').map((s) => s.trim()) : value,
15
+ );
16
+ }
package/tsconfig.json CHANGED
@@ -5,6 +5,9 @@
5
5
  "references": [
6
6
  {
7
7
  "path": "./tsconfig.lib.json"
8
+ },
9
+ {
10
+ "path": "./tsconfig.spec.json"
8
11
  }
9
12
  ],
10
13
  "compilerOptions": {
@@ -0,0 +1,12 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "types": ["node", "jest"],
7
+ "emitDecoratorMetadata": true,
8
+ "experimentalDecorators": true,
9
+ "target": "ES2021"
10
+ },
11
+ "include": ["src/**/*.spec.ts", "src/**/*.test.ts"]
12
+ }