@dismissible/nestjs-dismissible-item 0.0.2-canary.8976e84.0 → 0.0.2-canary.b0d8bfe.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/README.md +3 -15
- package/jest.config.ts +17 -0
- package/package.json +14 -2
- package/project.json +1 -1
- package/src/dismissible-item.factory.spec.ts +4 -24
- package/src/dismissible-item.factory.ts +8 -21
- package/src/dismissible-item.ts +2 -18
- package/tsconfig.json +3 -0
- package/tsconfig.spec.json +12 -0
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@ This library provides the foundational data structures for the Dismissible syste
|
|
|
10
10
|
|
|
11
11
|
- `DismissibleItemDto` - The core data transfer object representing a dismissible item
|
|
12
12
|
- `DismissibleItemFactory` - Factory for creating and manipulating dismissible items
|
|
13
|
-
- `BaseMetadata` - Type definition for item metadata
|
|
14
13
|
|
|
15
14
|
## Installation
|
|
16
15
|
|
|
@@ -28,24 +27,14 @@ The `DismissibleItemDto` class represents a dismissible item with the following
|
|
|
28
27
|
- `userId` - User identifier who owns the item
|
|
29
28
|
- `createdAt` - Timestamp when the item was created
|
|
30
29
|
- `dismissedAt` - Optional timestamp when the item was dismissed
|
|
31
|
-
- `metadata` - Optional metadata object (type-safe with generics)
|
|
32
30
|
|
|
33
31
|
```typescript
|
|
34
|
-
import { DismissibleItemDto
|
|
32
|
+
import { DismissibleItemDto } from '@dismissible/nestjs-dismissible-item';
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
version: number;
|
|
38
|
-
category: string;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const item: DismissibleItemDto<MyMetadata> = {
|
|
34
|
+
const item: DismissibleItemDto = {
|
|
42
35
|
id: 'welcome-banner',
|
|
43
36
|
userId: 'user-123',
|
|
44
37
|
createdAt: new Date(),
|
|
45
|
-
metadata: {
|
|
46
|
-
version: 2,
|
|
47
|
-
category: 'onboarding',
|
|
48
|
-
},
|
|
49
38
|
};
|
|
50
39
|
```
|
|
51
40
|
|
|
@@ -98,12 +87,11 @@ export class MyService {
|
|
|
98
87
|
The main data transfer object for dismissible items.
|
|
99
88
|
|
|
100
89
|
```typescript
|
|
101
|
-
class DismissibleItemDto
|
|
90
|
+
class DismissibleItemDto {
|
|
102
91
|
id: string;
|
|
103
92
|
userId: string;
|
|
104
93
|
createdAt: Date;
|
|
105
94
|
dismissedAt?: Date;
|
|
106
|
-
metadata?: TMetadata;
|
|
107
95
|
}
|
|
108
96
|
```
|
|
109
97
|
|
package/jest.config.ts
CHANGED
|
@@ -7,4 +7,21 @@ export default {
|
|
|
7
7
|
},
|
|
8
8
|
moduleFileExtensions: ['ts', 'js', 'html'],
|
|
9
9
|
coverageDirectory: '../../coverage/libs/dismissible-item',
|
|
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-dismissible-item",
|
|
3
|
-
"version": "0.0.2-canary.
|
|
3
|
+
"version": "0.0.2-canary.b0d8bfe.0",
|
|
4
4
|
"description": "Dismissible item library",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -12,11 +12,23 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@nestjs/common": "^11.0.0"
|
|
15
|
+
"@nestjs/common": "^11.0.0",
|
|
16
|
+
"@nestjs/swagger": "^11.0.0",
|
|
17
|
+
"class-validator": "^0.14.0",
|
|
18
|
+
"class-transformer": "^0.5.0"
|
|
16
19
|
},
|
|
17
20
|
"peerDependenciesMeta": {
|
|
18
21
|
"@nestjs/common": {
|
|
19
22
|
"optional": false
|
|
23
|
+
},
|
|
24
|
+
"@nestjs/swagger": {
|
|
25
|
+
"optional": false
|
|
26
|
+
},
|
|
27
|
+
"class-validator": {
|
|
28
|
+
"optional": false
|
|
29
|
+
},
|
|
30
|
+
"class-transformer": {
|
|
31
|
+
"optional": false
|
|
20
32
|
}
|
|
21
33
|
},
|
|
22
34
|
"keywords": [
|
package/project.json
CHANGED
|
@@ -13,41 +13,38 @@ describe('DismissibleItemFactory', () => {
|
|
|
13
13
|
const item = factory.create({
|
|
14
14
|
id: 'test-id',
|
|
15
15
|
createdAt: new Date('2024-01-15T10:00:00.000Z'),
|
|
16
|
+
userId: 'test-user-id',
|
|
16
17
|
});
|
|
17
18
|
|
|
18
19
|
expect(item).toBeInstanceOf(DismissibleItemDto);
|
|
19
20
|
expect(item.id).toBe('test-id');
|
|
20
21
|
expect(item.createdAt).toEqual(new Date('2024-01-15T10:00:00.000Z'));
|
|
22
|
+
expect(item.userId).toBe('test-user-id');
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
it('should handle optional properties when undefined', () => {
|
|
24
26
|
const item = factory.create({
|
|
25
27
|
id: 'test-id',
|
|
26
28
|
createdAt: new Date('2024-01-15T10:00:00.000Z'),
|
|
27
|
-
userId:
|
|
28
|
-
metadata: undefined,
|
|
29
|
+
userId: 'test-user-id',
|
|
29
30
|
dismissedAt: undefined,
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
expect(item.id).toBe('test-id');
|
|
33
34
|
expect(item.createdAt).toEqual(new Date('2024-01-15T10:00:00.000Z'));
|
|
34
|
-
expect(item.userId).
|
|
35
|
-
expect(item.metadata).toBeUndefined();
|
|
35
|
+
expect(item.userId).toBe('test-user-id');
|
|
36
36
|
expect(item.dismissedAt).toBeUndefined();
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
it('should include optional properties when provided', () => {
|
|
40
|
-
const metadata = { version: 2, category: 'test' };
|
|
41
40
|
const item = factory.create({
|
|
42
41
|
id: 'test-id',
|
|
43
42
|
createdAt: new Date('2024-01-15T10:00:00.000Z'),
|
|
44
43
|
userId: 'user-123',
|
|
45
|
-
metadata,
|
|
46
44
|
dismissedAt: new Date('2024-01-15T12:00:00.000Z'),
|
|
47
45
|
});
|
|
48
46
|
|
|
49
47
|
expect(item.userId).toBe('user-123');
|
|
50
|
-
expect(item.metadata).toEqual(metadata);
|
|
51
48
|
expect(item.dismissedAt).toEqual(new Date('2024-01-15T12:00:00.000Z'));
|
|
52
49
|
});
|
|
53
50
|
});
|
|
@@ -58,7 +55,6 @@ describe('DismissibleItemFactory', () => {
|
|
|
58
55
|
id: 'test-id',
|
|
59
56
|
createdAt: new Date('2024-01-15T10:00:00.000Z'),
|
|
60
57
|
userId: 'user-123',
|
|
61
|
-
metadata: { key: 'value' },
|
|
62
58
|
});
|
|
63
59
|
|
|
64
60
|
const cloned = factory.clone(original);
|
|
@@ -104,21 +100,5 @@ describe('DismissibleItemFactory', () => {
|
|
|
104
100
|
expect(restored.userId).toBe(dismissed.userId);
|
|
105
101
|
expect(restored.dismissedAt).toBeUndefined();
|
|
106
102
|
});
|
|
107
|
-
|
|
108
|
-
it('should preserve metadata when restoring', () => {
|
|
109
|
-
const metadata = { key: 'value', count: 42 };
|
|
110
|
-
const dismissed = factory.create({
|
|
111
|
-
id: 'test-id',
|
|
112
|
-
createdAt: new Date('2024-01-15T10:00:00.000Z'),
|
|
113
|
-
userId: 'user-123',
|
|
114
|
-
metadata,
|
|
115
|
-
dismissedAt: new Date('2024-01-15T12:00:00.000Z'),
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const restored = factory.createRestored(dismissed);
|
|
119
|
-
|
|
120
|
-
expect(restored.metadata).toEqual(metadata);
|
|
121
|
-
expect(restored.metadata).not.toBe(dismissed.metadata); // Different object reference
|
|
122
|
-
});
|
|
123
103
|
});
|
|
124
104
|
});
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { plainToInstance } from 'class-transformer';
|
|
3
|
-
import {
|
|
3
|
+
import { DismissibleItemDto } from './dismissible-item';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Options for creating a dismissible item.
|
|
7
7
|
*/
|
|
8
|
-
export interface ICreateDismissibleItemOptions
|
|
8
|
+
export interface ICreateDismissibleItemOptions {
|
|
9
9
|
id: string;
|
|
10
10
|
createdAt: Date;
|
|
11
|
-
userId
|
|
12
|
-
metadata?: TMetadata;
|
|
11
|
+
userId: string;
|
|
13
12
|
dismissedAt?: Date;
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -23,10 +22,8 @@ export class DismissibleItemFactory {
|
|
|
23
22
|
* Create a new DismissibleItemDto instance from the provided options.
|
|
24
23
|
* Uses plainToInstance to ensure the result is a proper class instance.
|
|
25
24
|
*/
|
|
26
|
-
create
|
|
27
|
-
options
|
|
28
|
-
): DismissibleItemDto<TMetadata> {
|
|
29
|
-
return plainToInstance(DismissibleItemDto<TMetadata>, options, {
|
|
25
|
+
create(options: ICreateDismissibleItemOptions): DismissibleItemDto {
|
|
26
|
+
return plainToInstance(DismissibleItemDto, options, {
|
|
30
27
|
excludeExtraneousValues: false,
|
|
31
28
|
enableImplicitConversion: true,
|
|
32
29
|
});
|
|
@@ -35,14 +32,11 @@ export class DismissibleItemFactory {
|
|
|
35
32
|
/**
|
|
36
33
|
* Create a clone of an existing DismissibleItemDto.
|
|
37
34
|
*/
|
|
38
|
-
clone
|
|
39
|
-
item: DismissibleItemDto<TMetadata>,
|
|
40
|
-
): DismissibleItemDto<TMetadata> {
|
|
35
|
+
clone(item: DismissibleItemDto): DismissibleItemDto {
|
|
41
36
|
return this.create({
|
|
42
37
|
id: item.id,
|
|
43
38
|
createdAt: item.createdAt,
|
|
44
39
|
userId: item.userId,
|
|
45
|
-
metadata: item.metadata,
|
|
46
40
|
dismissedAt: item.dismissedAt,
|
|
47
41
|
});
|
|
48
42
|
}
|
|
@@ -50,15 +44,11 @@ export class DismissibleItemFactory {
|
|
|
50
44
|
/**
|
|
51
45
|
* Create a dismissed version of an existing item.
|
|
52
46
|
*/
|
|
53
|
-
createDismissed
|
|
54
|
-
item: DismissibleItemDto<TMetadata>,
|
|
55
|
-
dismissedAt: Date,
|
|
56
|
-
): DismissibleItemDto<TMetadata> {
|
|
47
|
+
createDismissed(item: DismissibleItemDto, dismissedAt: Date): DismissibleItemDto {
|
|
57
48
|
return this.create({
|
|
58
49
|
id: item.id,
|
|
59
50
|
createdAt: item.createdAt,
|
|
60
51
|
userId: item.userId,
|
|
61
|
-
metadata: item.metadata,
|
|
62
52
|
dismissedAt,
|
|
63
53
|
});
|
|
64
54
|
}
|
|
@@ -67,14 +57,11 @@ export class DismissibleItemFactory {
|
|
|
67
57
|
* Create a restored (non-dismissed) version of an existing item.
|
|
68
58
|
* Removes the dismissedAt property.
|
|
69
59
|
*/
|
|
70
|
-
createRestored
|
|
71
|
-
item: DismissibleItemDto<TMetadata>,
|
|
72
|
-
): DismissibleItemDto<TMetadata> {
|
|
60
|
+
createRestored(item: DismissibleItemDto): DismissibleItemDto {
|
|
73
61
|
return this.create({
|
|
74
62
|
id: item.id,
|
|
75
63
|
createdAt: item.createdAt,
|
|
76
64
|
userId: item.userId,
|
|
77
|
-
metadata: item.metadata,
|
|
78
65
|
dismissedAt: undefined,
|
|
79
66
|
});
|
|
80
67
|
}
|
package/src/dismissible-item.ts
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
2
|
-
import { IsString, IsDate, IsOptional
|
|
2
|
+
import { IsString, IsDate, IsOptional } from 'class-validator';
|
|
3
3
|
import { Type } from 'class-transformer';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Base metadata type for dismissible items.
|
|
7
|
-
* Can be extended with custom metadata fields.
|
|
8
|
-
*/
|
|
9
|
-
export type BaseMetadata = Record<string, unknown>;
|
|
10
|
-
|
|
11
5
|
/**
|
|
12
6
|
* Represents a dismissible item in the system.
|
|
13
7
|
*/
|
|
14
|
-
export class DismissibleItemDto
|
|
8
|
+
export class DismissibleItemDto {
|
|
15
9
|
@ApiProperty({
|
|
16
10
|
description: 'Unique identifier for the item',
|
|
17
11
|
example: 'welcome-banner-v2',
|
|
@@ -42,14 +36,4 @@ export class DismissibleItemDto<TMetadata extends BaseMetadata = BaseMetadata> {
|
|
|
42
36
|
@IsDate()
|
|
43
37
|
@Type(() => Date)
|
|
44
38
|
dismissedAt?: Date;
|
|
45
|
-
|
|
46
|
-
@ApiPropertyOptional({
|
|
47
|
-
description: 'Optional metadata associated with the item',
|
|
48
|
-
example: { version: 2, category: 'promotional' },
|
|
49
|
-
type: 'object',
|
|
50
|
-
additionalProperties: true,
|
|
51
|
-
})
|
|
52
|
-
@IsOptional()
|
|
53
|
-
@IsObject()
|
|
54
|
-
metadata?: TMetadata;
|
|
55
39
|
}
|
package/tsconfig.json
CHANGED
|
@@ -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
|
+
}
|