@mars-stack/notifications 0.1.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/dist/chunk-G6F6UYJD.js +61 -0
- package/dist/index-C_rdct4Q.d.ts +77 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +19 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/server/index.ts
|
|
2
|
+
function createNotificationService(delegate, tx) {
|
|
3
|
+
return {
|
|
4
|
+
async create(userId, type, title, body, resourceId, resourceType) {
|
|
5
|
+
return delegate.create({
|
|
6
|
+
data: { userId, type, title, body, resourceId, resourceType }
|
|
7
|
+
});
|
|
8
|
+
},
|
|
9
|
+
async list(userId, options = {}) {
|
|
10
|
+
const { page = 1, limit = 20, unreadOnly = false } = options;
|
|
11
|
+
const skip = (page - 1) * limit;
|
|
12
|
+
const where = {
|
|
13
|
+
userId,
|
|
14
|
+
...unreadOnly && { read: false }
|
|
15
|
+
};
|
|
16
|
+
if (tx) {
|
|
17
|
+
const [notifications2, total2] = await tx.$transaction([
|
|
18
|
+
delegate.findMany({
|
|
19
|
+
where,
|
|
20
|
+
orderBy: { createdAt: "desc" },
|
|
21
|
+
skip,
|
|
22
|
+
take: limit
|
|
23
|
+
}),
|
|
24
|
+
delegate.count({ where })
|
|
25
|
+
]);
|
|
26
|
+
return {
|
|
27
|
+
notifications: notifications2,
|
|
28
|
+
pagination: { page, limit, total: total2, totalPages: Math.ceil(total2 / limit) }
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const notifications = await delegate.findMany({
|
|
32
|
+
where,
|
|
33
|
+
orderBy: { createdAt: "desc" },
|
|
34
|
+
skip,
|
|
35
|
+
take: limit
|
|
36
|
+
});
|
|
37
|
+
const total = await delegate.count({ where });
|
|
38
|
+
return {
|
|
39
|
+
notifications,
|
|
40
|
+
pagination: { page, limit, total, totalPages: Math.ceil(total / limit) }
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
async markAsRead(notificationId, userId) {
|
|
44
|
+
await delegate.updateMany({
|
|
45
|
+
where: { id: notificationId, userId },
|
|
46
|
+
data: { read: true, readAt: /* @__PURE__ */ new Date() }
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
async markAllAsRead(userId) {
|
|
50
|
+
await delegate.updateMany({
|
|
51
|
+
where: { userId, read: false },
|
|
52
|
+
data: { read: true, readAt: /* @__PURE__ */ new Date() }
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
async getUnreadCount(userId) {
|
|
56
|
+
return delegate.count({ where: { userId, read: false } });
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { createNotificationService };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
declare const NOTIFICATION_TYPES: {
|
|
2
|
+
readonly WELCOME: "welcome";
|
|
3
|
+
readonly BILLING_SUCCESS: "billing_success";
|
|
4
|
+
readonly BILLING_FAILED: "billing_failed";
|
|
5
|
+
readonly PASSWORD_CHANGED: "password_changed";
|
|
6
|
+
readonly ROLE_CHANGED: "role_changed";
|
|
7
|
+
readonly SYSTEM_ANNOUNCEMENT: "system_announcement";
|
|
8
|
+
};
|
|
9
|
+
type NotificationType = (typeof NOTIFICATION_TYPES)[keyof typeof NOTIFICATION_TYPES];
|
|
10
|
+
interface NotificationPayload {
|
|
11
|
+
type: NotificationType | string;
|
|
12
|
+
title: string;
|
|
13
|
+
body?: string;
|
|
14
|
+
resourceId?: string;
|
|
15
|
+
resourceType?: string;
|
|
16
|
+
}
|
|
17
|
+
interface NotificationRecord {
|
|
18
|
+
id: string;
|
|
19
|
+
userId: string;
|
|
20
|
+
type: string;
|
|
21
|
+
title: string;
|
|
22
|
+
body: string | null;
|
|
23
|
+
resourceId: string | null;
|
|
24
|
+
resourceType: string | null;
|
|
25
|
+
read: boolean;
|
|
26
|
+
readAt: Date | null;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
}
|
|
29
|
+
interface PaginatedNotifications {
|
|
30
|
+
notifications: NotificationRecord[];
|
|
31
|
+
pagination: {
|
|
32
|
+
page: number;
|
|
33
|
+
limit: number;
|
|
34
|
+
total: number;
|
|
35
|
+
totalPages: number;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
interface NotificationDelegate {
|
|
39
|
+
create(args: {
|
|
40
|
+
data: Record<string, unknown>;
|
|
41
|
+
}): Promise<NotificationRecord>;
|
|
42
|
+
findMany(args: {
|
|
43
|
+
where: Record<string, unknown>;
|
|
44
|
+
orderBy: Record<string, unknown>;
|
|
45
|
+
skip: number;
|
|
46
|
+
take: number;
|
|
47
|
+
}): Promise<NotificationRecord[]>;
|
|
48
|
+
count(args: {
|
|
49
|
+
where: Record<string, unknown>;
|
|
50
|
+
}): Promise<number>;
|
|
51
|
+
updateMany(args: {
|
|
52
|
+
where: Record<string, unknown>;
|
|
53
|
+
data: Record<string, unknown>;
|
|
54
|
+
}): Promise<{
|
|
55
|
+
count: number;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
interface NotificationTransactionRunner {
|
|
59
|
+
$transaction<T extends unknown[]>(operations: [...{
|
|
60
|
+
[K in keyof T]: Promise<T[K]>;
|
|
61
|
+
}]): Promise<T>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare function createNotificationService(delegate: NotificationDelegate, tx?: NotificationTransactionRunner): {
|
|
65
|
+
create(userId: string, type: string, title: string, body?: string, resourceId?: string, resourceType?: string): Promise<NotificationRecord>;
|
|
66
|
+
list(userId: string, options?: {
|
|
67
|
+
page?: number;
|
|
68
|
+
limit?: number;
|
|
69
|
+
unreadOnly?: boolean;
|
|
70
|
+
}): Promise<PaginatedNotifications>;
|
|
71
|
+
markAsRead(notificationId: string, userId: string): Promise<void>;
|
|
72
|
+
markAllAsRead(userId: string): Promise<void>;
|
|
73
|
+
getUnreadCount(userId: string): Promise<number>;
|
|
74
|
+
};
|
|
75
|
+
type NotificationService = ReturnType<typeof createNotificationService>;
|
|
76
|
+
|
|
77
|
+
export { NOTIFICATION_TYPES as N, type PaginatedNotifications as P, type NotificationDelegate as a, type NotificationPayload as b, type NotificationRecord as c, type NotificationService as d, type NotificationTransactionRunner as e, type NotificationType as f, createNotificationService as g };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { N as NOTIFICATION_TYPES, a as NotificationDelegate, b as NotificationPayload, c as NotificationRecord, d as NotificationService, e as NotificationTransactionRunner, f as NotificationType, P as PaginatedNotifications, g as createNotificationService } from './index-C_rdct4Q.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
declare const listNotificationsSchema: z.ZodObject<{
|
|
5
|
+
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
6
|
+
limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
7
|
+
unreadOnly: z.ZodDefault<z.ZodCoercedBoolean<unknown>>;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
type ListNotificationsParams = z.infer<typeof listNotificationsSchema>;
|
|
10
|
+
|
|
11
|
+
export { type ListNotificationsParams, listNotificationsSchema };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export { createNotificationService } from './chunk-G6F6UYJD.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// src/types.ts
|
|
5
|
+
var NOTIFICATION_TYPES = {
|
|
6
|
+
WELCOME: "welcome",
|
|
7
|
+
BILLING_SUCCESS: "billing_success",
|
|
8
|
+
BILLING_FAILED: "billing_failed",
|
|
9
|
+
PASSWORD_CHANGED: "password_changed",
|
|
10
|
+
ROLE_CHANGED: "role_changed",
|
|
11
|
+
SYSTEM_ANNOUNCEMENT: "system_announcement"
|
|
12
|
+
};
|
|
13
|
+
var listNotificationsSchema = z.object({
|
|
14
|
+
page: z.coerce.number().int().positive().default(1),
|
|
15
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
16
|
+
unreadOnly: z.coerce.boolean().default(false)
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export { NOTIFICATION_TYPES, listNotificationsSchema };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as NotificationService, g as createNotificationService } from '../index-C_rdct4Q.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createNotificationService } from '../chunk-G6F6UYJD.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mars-stack/notifications",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Notifications module for MARS applications — in-app notifications with CRUD, polling, and digest",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/greaveselliott/mars.git",
|
|
9
|
+
"directory": "packages/notifications"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./server": {
|
|
18
|
+
"types": "./dist/server/index.d.ts",
|
|
19
|
+
"import": "./dist/server/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "restricted"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch",
|
|
31
|
+
"test": "vitest run --passWithNoTests",
|
|
32
|
+
"prepublishOnly": "yarn build"
|
|
33
|
+
},
|
|
34
|
+
"sideEffects": false,
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"zod": "^4.3.6"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@prisma/client": ">=5.0.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependenciesMeta": {
|
|
42
|
+
"@prisma/client": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"tsup": "^8.0.0",
|
|
48
|
+
"typescript": "^5.7.0",
|
|
49
|
+
"vitest": "^3.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|