@blocklet/sdk 1.16.41-beta-20250325-154552-2bf78c26 → 1.16.41-beta-20250331-010247-966fcfb0
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/lib/config.js +3 -3
- package/lib/middlewares/fallback.d.ts +4 -1
- package/lib/middlewares/fallback.js +119 -33
- package/lib/middlewares/index.d.ts +9 -1
- package/lib/service/auth.d.ts +7 -1
- package/lib/service/auth.js +35 -0
- package/lib/types/notification.d.ts +14 -0
- package/lib/validators/notification.d.ts +41 -0
- package/lib/validators/notification.js +73 -1
- package/package.json +8 -8
package/lib/config.js
CHANGED
|
@@ -293,9 +293,9 @@ const getBlockletJs = (pageGroup = '', pathPrefix = '', source = blockletJs) =>
|
|
|
293
293
|
if (pageGroup) {
|
|
294
294
|
copy = copy.replace('pageGroup: "",', `pageGroup: "${pageGroup}",`);
|
|
295
295
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
const { mountPoint } = componentStore.find((x) => x.did === componentDid);
|
|
296
|
+
const componentDid = process.env.BLOCKLET_COMPONENT_DID;
|
|
297
|
+
if (pathPrefix && componentDid) {
|
|
298
|
+
const { mountPoint } = componentStore.find((x) => x.did === componentDid) || {};
|
|
299
299
|
copy = copy
|
|
300
300
|
.replace(`prefix: "${normalize(mountPoint)}",`, `prefix: "${normalize(pathPrefix)}",`)
|
|
301
301
|
.replace('prefix: "/",', `prefix: "${normalize(pathPrefix)}",`);
|
|
@@ -7,7 +7,10 @@ type PageData = {
|
|
|
7
7
|
};
|
|
8
8
|
type FallbackOptions = {
|
|
9
9
|
root?: string | undefined;
|
|
10
|
-
getPageData?: (req: Request) => Promise<PageData>;
|
|
10
|
+
getPageData?: (req: Request) => PageData | Promise<PageData>;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
maxLength?: number;
|
|
13
|
+
cacheTtl?: number;
|
|
11
14
|
};
|
|
12
15
|
declare const fallback: (file: string, options?: FallbackOptions) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
13
16
|
export = fallback;
|
|
@@ -2,74 +2,160 @@
|
|
|
2
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
|
-
const fs_1 = require("fs");
|
|
5
|
+
const fs_1 = __importDefault(require("fs"));
|
|
6
6
|
const path_1 = require("path");
|
|
7
7
|
const ufo_1 = require("ufo");
|
|
8
8
|
const escape_1 = __importDefault(require("lodash/escape"));
|
|
9
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
9
10
|
const constant_1 = require("@blocklet/constant");
|
|
10
11
|
const config_1 = require("../config");
|
|
12
|
+
// Cache configurations
|
|
13
|
+
const DEFAULT_CACHE_TTL = 1 * 60 * 1000; // 1 minute
|
|
14
|
+
const cache = new Map();
|
|
15
|
+
// Pre-compile regex patterns for better performance
|
|
16
|
+
const TITLE_TAG_REGEX = /<title>(.+)<\/title>/;
|
|
17
|
+
const HEAD_END_TAG = '</head>';
|
|
18
|
+
const buildOpenGraph = (pageData, appUrl) => {
|
|
19
|
+
const parts = [
|
|
20
|
+
`<meta property="og:title" content="${pageData.title}" data-react-helmet="true" />`,
|
|
21
|
+
`<meta property="og:description" content="${pageData.description}" data-react-helmet="true" />`,
|
|
22
|
+
'<meta property="og:type" content="website" data-react-helmet="true" />',
|
|
23
|
+
`<meta property="og:url" content="${appUrl}" data-react-helmet="true" />`,
|
|
24
|
+
`<meta property="og:image" content="${pageData.ogImage}" data-react-helmet="true" />`,
|
|
25
|
+
'<meta name="twitter:card" content="summary_large_image" data-react-helmet="true" />',
|
|
26
|
+
];
|
|
27
|
+
return parts.join('\n');
|
|
28
|
+
};
|
|
29
|
+
const validatePageData = (data, maxLength) => {
|
|
30
|
+
if (data.title && data.title.length > maxLength) {
|
|
31
|
+
throw new Error('Title too long');
|
|
32
|
+
}
|
|
33
|
+
if (data.description && data.description.length > maxLength) {
|
|
34
|
+
throw new Error('Description too long');
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const generateETag = (content) => {
|
|
38
|
+
const hash = crypto_1.default.createHash('sha1');
|
|
39
|
+
hash.update(content);
|
|
40
|
+
return `W/"${hash.digest('base64')}"`;
|
|
41
|
+
};
|
|
42
|
+
const getCacheKey = (filePath, pageGroup, pathPrefix) => {
|
|
43
|
+
return `${filePath}:${pageGroup}:${pathPrefix}`;
|
|
44
|
+
};
|
|
45
|
+
const tryWithTimeout = (asyncFn, timeout) => {
|
|
46
|
+
if (typeof asyncFn !== 'function') {
|
|
47
|
+
throw new Error('Must provide a valid asyncFn function');
|
|
48
|
+
}
|
|
49
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
50
|
+
return new Promise(async (resolve, reject) => {
|
|
51
|
+
const timer = setTimeout(() => {
|
|
52
|
+
reject(new Error(`Operation timed out after ${timeout} ms`));
|
|
53
|
+
}, timeout);
|
|
54
|
+
try {
|
|
55
|
+
const result = await asyncFn();
|
|
56
|
+
resolve(result);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
reject(err);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
};
|
|
11
66
|
const fallback = (file, options = {}) => {
|
|
12
67
|
const filePath = options.root ? (0, path_1.join)(options.root, file) : file;
|
|
13
|
-
|
|
68
|
+
// Check file existence during initialization
|
|
69
|
+
if (!fs_1.default.existsSync(filePath)) {
|
|
14
70
|
throw new Error(`Fallback file not found at: ${filePath}`);
|
|
15
71
|
}
|
|
16
72
|
return async (req, res, next) => {
|
|
17
|
-
|
|
18
|
-
|
|
73
|
+
try {
|
|
74
|
+
// Skip non-HTML requests early
|
|
75
|
+
if (!(req.method === 'GET' || req.method === 'HEAD') || !req.accepts('html') || constant_1.RESOURCE_PATTERN.test(req.path)) {
|
|
76
|
+
next();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
19
79
|
const pageGroup = req.headers['x-page-group'] || '';
|
|
20
80
|
const pathPrefix = req.headers['x-path-prefix'] || '';
|
|
21
|
-
const
|
|
81
|
+
const cacheKey = getCacheKey(filePath, pageGroup, pathPrefix);
|
|
82
|
+
// Check cache first
|
|
83
|
+
const cached = cache.get(cacheKey);
|
|
84
|
+
const cacheTtl = options.cacheTtl || DEFAULT_CACHE_TTL;
|
|
85
|
+
if (cached && Date.now() - cached.timestamp < cacheTtl) {
|
|
86
|
+
if (cached.pageGroup === pageGroup && cached.pathPrefix === pathPrefix) {
|
|
87
|
+
res.setHeader('X-Cache', 'HIT');
|
|
88
|
+
res.setHeader('ETag', cached.etag);
|
|
89
|
+
res.type('html');
|
|
90
|
+
res.send(cached.html);
|
|
91
|
+
if (process.env.NODE_ENV === 'test') {
|
|
92
|
+
next(cached.html);
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Get page data with timeout protection
|
|
98
|
+
const pageData = await tryWithTimeout(options.getPageData ? () => options.getPageData(req) : () => Promise.resolve({}), options.timeout || 5000);
|
|
99
|
+
validatePageData(pageData, options.maxLength || 1000);
|
|
22
100
|
pageData.title = (0, escape_1.default)(pageData.title || config_1.env.appName);
|
|
23
101
|
pageData.description = (0, escape_1.default)(pageData.description || config_1.env.appDescription);
|
|
24
102
|
pageData.ogImage = pageData.ogImage || (0, ufo_1.joinURL)(config_1.env.appUrl || '/', '/.well-known/service/blocklet/og.png');
|
|
25
|
-
let source =
|
|
26
|
-
//
|
|
103
|
+
let source = await fs_1.default.promises.readFile(filePath, 'utf8');
|
|
104
|
+
// Optimize string replacements
|
|
27
105
|
if (pageData.title) {
|
|
28
|
-
if (source.
|
|
29
|
-
source = source.replace(
|
|
106
|
+
if (!source.includes('<title>')) {
|
|
107
|
+
source = source.replace(HEAD_END_TAG, `<title>${pageData.title}</title>${HEAD_END_TAG}`);
|
|
30
108
|
}
|
|
31
109
|
else {
|
|
32
|
-
source = source.replace(
|
|
110
|
+
source = source.replace(TITLE_TAG_REGEX, `<title>${pageData.title}</title>`);
|
|
33
111
|
}
|
|
34
112
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (source.indexOf('<meta name="description"') === -1) {
|
|
38
|
-
source = source.replace('</head>', `<meta name="description" content="${pageData.description}" data-react-helmet="true" /></head>`);
|
|
39
|
-
}
|
|
113
|
+
if (pageData.description && !source.includes('<meta name="description"')) {
|
|
114
|
+
source = source.replace(HEAD_END_TAG, `<meta name="description" content="${pageData.description}" data-react-helmet="true" />${HEAD_END_TAG}`);
|
|
40
115
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const og = `<meta property="og:title" content="${pageData.title}" data-react-helmet="true" />
|
|
44
|
-
<meta property="og:description" content="${pageData.description}" data-react-helmet="true" />
|
|
45
|
-
<meta property="og:type" content="website" data-react-helmet="true" />
|
|
46
|
-
<meta property="og:url" content="${config_1.env.appUrl}" data-react-helmet="true" />
|
|
47
|
-
<meta property="og:image" content="${pageData.ogImage}" data-react-helmet="true" />
|
|
48
|
-
<meta name="twitter:card" content="summary_large_image" data-react-helmet="true" />`;
|
|
49
|
-
source = source.replace('</head>', `${og}</head>`);
|
|
116
|
+
if (!source.includes('meta property="og:image"')) {
|
|
117
|
+
source = source.replace(HEAD_END_TAG, `${buildOpenGraph(pageData, config_1.env.appUrl || '/')}\n${HEAD_END_TAG}`);
|
|
50
118
|
}
|
|
51
119
|
if (pageData.embed) {
|
|
52
|
-
source = source.replace(
|
|
120
|
+
source = source.replace(HEAD_END_TAG, `<link rel="blocklet-open-embed" type="application/json" href="${pageData.embed}" />${HEAD_END_TAG}`);
|
|
53
121
|
}
|
|
54
|
-
// inline blocklet.js
|
|
55
122
|
const blockletJs = (0, config_1.getBlockletJs)(pageGroup, pathPrefix);
|
|
56
123
|
if (blockletJs) {
|
|
57
124
|
source = source
|
|
58
125
|
.replace('<script src="__blocklet__.js"></script>', `<script>${blockletJs}</script>`)
|
|
59
126
|
.replace('<script src="__meta__.js"></script>', `<script>${blockletJs}</script>`);
|
|
60
127
|
}
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
128
|
+
// Cache the processed response
|
|
129
|
+
const etag = generateETag(source);
|
|
130
|
+
cache.set(cacheKey, {
|
|
131
|
+
html: source,
|
|
132
|
+
timestamp: Date.now(),
|
|
133
|
+
etag,
|
|
134
|
+
pageGroup: pageGroup,
|
|
135
|
+
pathPrefix: pathPrefix,
|
|
136
|
+
});
|
|
137
|
+
// Set response headers
|
|
138
|
+
if (options.cacheTtl) {
|
|
139
|
+
res.setHeader('Cache-Control', `public, max-age=${options.cacheTtl}`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
res.setHeader('Surrogate-Control', 'no-store');
|
|
143
|
+
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
144
|
+
res.setHeader('Expires', '0');
|
|
145
|
+
}
|
|
146
|
+
res.setHeader('X-Cache', 'MISS');
|
|
147
|
+
res.setHeader('ETag', etag);
|
|
148
|
+
res.type('html');
|
|
65
149
|
res.send(source);
|
|
66
|
-
// istanbul-ignore-next
|
|
67
150
|
if (process.env.NODE_ENV === 'test') {
|
|
68
151
|
next(source);
|
|
69
152
|
}
|
|
70
153
|
}
|
|
71
|
-
|
|
72
|
-
|
|
154
|
+
catch (err) {
|
|
155
|
+
if (process.env.NODE_ENV === 'test') {
|
|
156
|
+
console.error('error', err);
|
|
157
|
+
}
|
|
158
|
+
next(err);
|
|
73
159
|
}
|
|
74
160
|
};
|
|
75
161
|
};
|
|
@@ -24,12 +24,20 @@ declare const _default: {
|
|
|
24
24
|
};
|
|
25
25
|
fallback: (file: string, options?: {
|
|
26
26
|
root?: string | undefined;
|
|
27
|
-
getPageData?: (req: import("express").Request) =>
|
|
27
|
+
getPageData?: (req: import("express").Request) => {
|
|
28
|
+
title?: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
ogImage?: string;
|
|
31
|
+
embed?: string;
|
|
32
|
+
} | Promise<{
|
|
28
33
|
title?: string;
|
|
29
34
|
description?: string;
|
|
30
35
|
ogImage?: string;
|
|
31
36
|
embed?: string;
|
|
32
37
|
}>;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
maxLength?: number;
|
|
40
|
+
cacheTtl?: number;
|
|
33
41
|
}) => (req: import("express").Request, res: import("express").Response, next: import("express").NextFunction) => Promise<void>;
|
|
34
42
|
sitemap: (generatorFn: (fn: (item: {
|
|
35
43
|
url: string;
|
package/lib/service/auth.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ type PartialDeep<T> = {
|
|
|
3
3
|
[K in keyof T]?: T[K] extends object ? PartialDeep<T[K]> : T[K];
|
|
4
4
|
};
|
|
5
5
|
type OmitTeamDid<T> = PartialDeep<Omit<T, 'teamDid'>>;
|
|
6
|
+
type RequestHeaders = {
|
|
7
|
+
headers: {
|
|
8
|
+
cookie: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
6
11
|
declare class AuthService {
|
|
7
12
|
constructor(httpEndpoint?: string);
|
|
8
13
|
}
|
|
@@ -62,6 +67,7 @@ interface AuthService {
|
|
|
62
67
|
getComponent(did: string): Promise<Client.ComponentState>;
|
|
63
68
|
getTrustedDomains(): Promise<string[]>;
|
|
64
69
|
getVault(): Promise<string>;
|
|
65
|
-
updateUserAddress(args: OmitTeamDid<Client.RequestUpdateUserAddressInput
|
|
70
|
+
updateUserAddress(args: OmitTeamDid<Client.RequestUpdateUserAddressInput>, options: RequestHeaders): Promise<Client.ResponseUser>;
|
|
71
|
+
updateUserInfo(userInfo: ABTNodeClient.UserInfoInput, options: RequestHeaders): Promise<Client.ResponseUser>;
|
|
66
72
|
}
|
|
67
73
|
export = AuthService;
|
package/lib/service/auth.js
CHANGED
|
@@ -71,6 +71,7 @@ class AuthService {
|
|
|
71
71
|
'updateUserExtra',
|
|
72
72
|
// updateUserInfo
|
|
73
73
|
'updateUserAddress',
|
|
74
|
+
'updateUserInfo',
|
|
74
75
|
// tagging
|
|
75
76
|
'getTags',
|
|
76
77
|
'createTag',
|
|
@@ -201,6 +202,40 @@ class AuthService {
|
|
|
201
202
|
const { blocklet } = await this.getBlocklet();
|
|
202
203
|
return (0, security_1.verifyVault)(blocklet.vaults, wallet.address);
|
|
203
204
|
};
|
|
205
|
+
this.updateUserInfo = async (userInfo, options) => {
|
|
206
|
+
const fn = client.updateUserInfo;
|
|
207
|
+
if (!options?.headers?.cookie) {
|
|
208
|
+
throw new Error('Missing required authentication cookie in request headers');
|
|
209
|
+
}
|
|
210
|
+
if (!userInfo?.did) {
|
|
211
|
+
throw new Error('Missing required user DID in address update args');
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
// @ts-ignore
|
|
215
|
+
const res = await fn({ input: { user: userInfo, teamDid } }, options);
|
|
216
|
+
return res;
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
throw new Error(err.response ? err.response.data : err.message);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
this.updateUserAddress = async (args, options) => {
|
|
223
|
+
const fn = client.updateUserAddress;
|
|
224
|
+
if (!options?.headers?.cookie) {
|
|
225
|
+
throw new Error('Missing required authentication cookie in request headers');
|
|
226
|
+
}
|
|
227
|
+
if (!args?.did) {
|
|
228
|
+
throw new Error('Missing required user DID in address update args');
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
// @ts-ignore
|
|
232
|
+
const res = await fn({ input: { ...args, teamDid } }, options);
|
|
233
|
+
return res;
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
throw new Error(err.response ? err.response.data : err.message);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
204
239
|
// eslint-disable-next-line no-constructor-return
|
|
205
240
|
return new Proxy(this, {
|
|
206
241
|
get(target, propKey) {
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export interface TActivityTarget {
|
|
2
|
+
desc?: any;
|
|
3
|
+
id: string;
|
|
4
|
+
image?: any;
|
|
5
|
+
name?: any;
|
|
6
|
+
type: 'discussion' | 'blog' | 'doc' | 'bookmark' | 'comment' | 'user';
|
|
7
|
+
}
|
|
1
8
|
export type TChannelEvent = string;
|
|
2
9
|
export interface TDataAsset {
|
|
3
10
|
chainHost: string;
|
|
@@ -61,6 +68,7 @@ export interface TMessage {
|
|
|
61
68
|
}
|
|
62
69
|
export interface TNotification {
|
|
63
70
|
actions?: TNotificationAction[];
|
|
71
|
+
activity?: TNotificationActivity;
|
|
64
72
|
appInfo?: object;
|
|
65
73
|
attachments?: TNotificationAttachment[];
|
|
66
74
|
blocks?: TNotificationAttachment[];
|
|
@@ -84,6 +92,12 @@ export interface TNotificationAction {
|
|
|
84
92
|
name: string;
|
|
85
93
|
title?: string;
|
|
86
94
|
}
|
|
95
|
+
export interface TNotificationActivity {
|
|
96
|
+
actor: unknown;
|
|
97
|
+
meta?: any;
|
|
98
|
+
target: TActivityTarget;
|
|
99
|
+
type: 'comment' | 'like' | 'follow' | 'tips' | 'mention' | 'assign';
|
|
100
|
+
}
|
|
87
101
|
export interface TNotificationAttachment {
|
|
88
102
|
data?: any;
|
|
89
103
|
fields?: any;
|
|
@@ -6,6 +6,22 @@ declare const TYPES: {
|
|
|
6
6
|
HI: string;
|
|
7
7
|
PASSTHROUGH: string;
|
|
8
8
|
};
|
|
9
|
+
declare const ACTIVITY_TYPES: {
|
|
10
|
+
COMMENT: string;
|
|
11
|
+
LIKE: string;
|
|
12
|
+
FOLLOW: string;
|
|
13
|
+
TIPS: string;
|
|
14
|
+
MENTION: string;
|
|
15
|
+
ASSIGN: string;
|
|
16
|
+
};
|
|
17
|
+
declare const ACTIVITY_TARGET_TYPES: {
|
|
18
|
+
DISCUSSION: string;
|
|
19
|
+
BLOG: string;
|
|
20
|
+
DOC: string;
|
|
21
|
+
BOOKMARK: string;
|
|
22
|
+
COMMENT: string;
|
|
23
|
+
USER: string;
|
|
24
|
+
};
|
|
9
25
|
declare const assetSchema: JOI.ObjectSchema<any>;
|
|
10
26
|
declare const vcSchema: JOI.ObjectSchema<any>;
|
|
11
27
|
declare const tokenSchema: JOI.ObjectSchema<any>;
|
|
@@ -19,6 +35,8 @@ declare const attachmentSchema: JOI.ObjectSchema<any>;
|
|
|
19
35
|
declare const notificationTypeSchema: JOI.ObjectSchema<any>;
|
|
20
36
|
declare const connectTypeSchema: JOI.ObjectSchema<any>;
|
|
21
37
|
declare const feedTypeSchema: JOI.ObjectSchema<any>;
|
|
38
|
+
declare const activityTargetSchema: JOI.ObjectSchema<any>;
|
|
39
|
+
declare const notificationActivitySchema: JOI.ObjectSchema<any>;
|
|
22
40
|
declare const notificationSchema: JOI.ObjectSchema<any>;
|
|
23
41
|
declare const messageSchema: JOI.ObjectSchema<any>;
|
|
24
42
|
declare const inputNotificationSchema: JOI.ArraySchema<any[]>;
|
|
@@ -30,6 +48,7 @@ export declare const validateMessage: any;
|
|
|
30
48
|
export declare const validateChannelEvent: any;
|
|
31
49
|
export declare const validateOption: any;
|
|
32
50
|
export declare const validateEmail: any;
|
|
51
|
+
export declare const validateActivity: any;
|
|
33
52
|
export { tokenSchema };
|
|
34
53
|
export { actionSchema };
|
|
35
54
|
export { assetSchema };
|
|
@@ -46,6 +65,9 @@ export { optionSchema };
|
|
|
46
65
|
export { channelEventSchema };
|
|
47
66
|
export { TYPES as NOTIFICATION_TYPES };
|
|
48
67
|
export { inputNotificationSchema, notificationTypeSchema, connectTypeSchema, feedTypeSchema };
|
|
68
|
+
export { ACTIVITY_TYPES, ACTIVITY_TARGET_TYPES };
|
|
69
|
+
export { notificationActivitySchema };
|
|
70
|
+
export { activityTargetSchema };
|
|
49
71
|
declare const _default: {
|
|
50
72
|
validateReceiver: any;
|
|
51
73
|
validateNotification: any;
|
|
@@ -73,5 +95,24 @@ declare const _default: {
|
|
|
73
95
|
HI: string;
|
|
74
96
|
PASSTHROUGH: string;
|
|
75
97
|
};
|
|
98
|
+
ACTIVITY_TYPES: {
|
|
99
|
+
COMMENT: string;
|
|
100
|
+
LIKE: string;
|
|
101
|
+
FOLLOW: string;
|
|
102
|
+
TIPS: string;
|
|
103
|
+
MENTION: string;
|
|
104
|
+
ASSIGN: string;
|
|
105
|
+
};
|
|
106
|
+
ACTIVITY_TARGET_TYPES: {
|
|
107
|
+
DISCUSSION: string;
|
|
108
|
+
BLOG: string;
|
|
109
|
+
DOC: string;
|
|
110
|
+
BOOKMARK: string;
|
|
111
|
+
COMMENT: string;
|
|
112
|
+
USER: string;
|
|
113
|
+
};
|
|
114
|
+
validateActivity: any;
|
|
115
|
+
notificationActivitySchema: JOI.ObjectSchema<any>;
|
|
116
|
+
activityTargetSchema: JOI.ObjectSchema<any>;
|
|
76
117
|
};
|
|
77
118
|
export default _default;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.feedTypeSchema = exports.connectTypeSchema = exports.notificationTypeSchema = exports.inputNotificationSchema = exports.NOTIFICATION_TYPES = exports.channelEventSchema = exports.optionSchema = exports.messageSchema = exports.notificationSchema = exports.attachmentSchema = exports.dappSchema = exports.imageSchema = exports.linkSchema = exports.textSchema = exports.transactionSchema = exports.vcSchema = exports.assetSchema = exports.actionSchema = exports.tokenSchema = exports.validateEmail = exports.validateOption = exports.validateChannelEvent = exports.validateMessage = exports.validateNotification = exports.validateReceiver = void 0;
|
|
6
|
+
exports.activityTargetSchema = exports.notificationActivitySchema = exports.ACTIVITY_TARGET_TYPES = exports.ACTIVITY_TYPES = exports.feedTypeSchema = exports.connectTypeSchema = exports.notificationTypeSchema = exports.inputNotificationSchema = exports.NOTIFICATION_TYPES = exports.channelEventSchema = exports.optionSchema = exports.messageSchema = exports.notificationSchema = exports.attachmentSchema = exports.dappSchema = exports.imageSchema = exports.linkSchema = exports.textSchema = exports.transactionSchema = exports.vcSchema = exports.assetSchema = exports.actionSchema = exports.tokenSchema = exports.validateActivity = exports.validateEmail = exports.validateOption = exports.validateChannelEvent = exports.validateMessage = exports.validateNotification = exports.validateReceiver = void 0;
|
|
7
7
|
const joi_1 = __importDefault(require("joi"));
|
|
8
8
|
const extension_1 = require("@blocklet/meta/lib/extension");
|
|
9
9
|
const Joi = joi_1.default.extend(extension_1.didExtension);
|
|
@@ -33,6 +33,24 @@ const ATTACHMENT_TYPES = {
|
|
|
33
33
|
LINK: 'link',
|
|
34
34
|
SECTION: 'section',
|
|
35
35
|
};
|
|
36
|
+
const ACTIVITY_TYPES = {
|
|
37
|
+
COMMENT: 'comment',
|
|
38
|
+
LIKE: 'like',
|
|
39
|
+
FOLLOW: 'follow',
|
|
40
|
+
TIPS: 'tips',
|
|
41
|
+
MENTION: 'mention',
|
|
42
|
+
ASSIGN: 'assign',
|
|
43
|
+
};
|
|
44
|
+
exports.ACTIVITY_TYPES = ACTIVITY_TYPES;
|
|
45
|
+
const ACTIVITY_TARGET_TYPES = {
|
|
46
|
+
DISCUSSION: 'discussion',
|
|
47
|
+
BLOG: 'blog',
|
|
48
|
+
DOC: 'doc',
|
|
49
|
+
BOOKMARK: 'bookmark',
|
|
50
|
+
COMMENT: 'comment',
|
|
51
|
+
USER: 'user',
|
|
52
|
+
};
|
|
53
|
+
exports.ACTIVITY_TARGET_TYPES = ACTIVITY_TARGET_TYPES;
|
|
36
54
|
const assetSchema = Joi.object({
|
|
37
55
|
did: Joi.DID().trim().required(),
|
|
38
56
|
chainHost: Joi.string().uri().required(),
|
|
@@ -162,6 +180,52 @@ const feedTypeSchema = Joi.object({
|
|
|
162
180
|
.required()
|
|
163
181
|
.meta({ className: 'TNotificationFeed' });
|
|
164
182
|
exports.feedTypeSchema = feedTypeSchema;
|
|
183
|
+
const activityTargetSchema = Joi.object({
|
|
184
|
+
type: Joi.string()
|
|
185
|
+
.valid(...Object.values(ACTIVITY_TARGET_TYPES))
|
|
186
|
+
.required(),
|
|
187
|
+
id: Joi.string().required(),
|
|
188
|
+
name: Joi.when('type', {
|
|
189
|
+
is: ACTIVITY_TARGET_TYPES.USER,
|
|
190
|
+
then: Joi.forbidden(),
|
|
191
|
+
otherwise: Joi.string().allow('').optional(),
|
|
192
|
+
}),
|
|
193
|
+
desc: Joi.when('type', {
|
|
194
|
+
is: ACTIVITY_TARGET_TYPES.USER,
|
|
195
|
+
then: Joi.forbidden(),
|
|
196
|
+
otherwise: Joi.string().allow('').optional(),
|
|
197
|
+
}),
|
|
198
|
+
image: Joi.when('type', {
|
|
199
|
+
is: ACTIVITY_TARGET_TYPES.USER,
|
|
200
|
+
then: Joi.forbidden(),
|
|
201
|
+
otherwise: Joi.string().allow('').optional(),
|
|
202
|
+
}),
|
|
203
|
+
}).meta({ className: 'TActivityTarget' });
|
|
204
|
+
exports.activityTargetSchema = activityTargetSchema;
|
|
205
|
+
const notificationActivitySchema = Joi.object({
|
|
206
|
+
type: Joi.string()
|
|
207
|
+
.valid(...Object.values(ACTIVITY_TYPES))
|
|
208
|
+
.required(),
|
|
209
|
+
actor: Joi.DID().trim().required(),
|
|
210
|
+
target: activityTargetSchema.required(),
|
|
211
|
+
meta: Joi.when('type', {
|
|
212
|
+
is: ACTIVITY_TYPES.TIPS,
|
|
213
|
+
then: Joi.object({
|
|
214
|
+
amount: Joi.number().required(),
|
|
215
|
+
symbol: Joi.string().required(),
|
|
216
|
+
chainId: Joi.string().required(),
|
|
217
|
+
}).required(),
|
|
218
|
+
otherwise: Joi.when('type', {
|
|
219
|
+
is: ACTIVITY_TYPES.COMMENT,
|
|
220
|
+
then: Joi.object({
|
|
221
|
+
id: Joi.string().required(),
|
|
222
|
+
content: Joi.string().required(),
|
|
223
|
+
}).required(),
|
|
224
|
+
otherwise: Joi.object().optional(),
|
|
225
|
+
}),
|
|
226
|
+
}),
|
|
227
|
+
}).meta({ className: 'TNotificationActivity' });
|
|
228
|
+
exports.notificationActivitySchema = notificationActivitySchema;
|
|
165
229
|
const notificationSchema = Joi.object({
|
|
166
230
|
type: Joi.string().valid(...Object.values(TYPES)),
|
|
167
231
|
id: Joi.string().optional(),
|
|
@@ -182,6 +246,8 @@ const notificationSchema = Joi.object({
|
|
|
182
246
|
actions: Joi.array().items(actionSchema).default([]),
|
|
183
247
|
appInfo: Joi.object().optional(),
|
|
184
248
|
poweredBy: Joi.object().optional(),
|
|
249
|
+
// notification activity v1.16.41
|
|
250
|
+
activity: notificationActivitySchema.optional(),
|
|
185
251
|
})
|
|
186
252
|
.required()
|
|
187
253
|
.meta({ className: 'TNotification' });
|
|
@@ -225,6 +291,7 @@ exports.validateMessage = messageSchema.validateAsync.bind(messageSchema);
|
|
|
225
291
|
exports.validateChannelEvent = channelEventSchema.validateAsync.bind(channelEventSchema);
|
|
226
292
|
exports.validateOption = optionSchema.validateAsync.bind(optionSchema);
|
|
227
293
|
exports.validateEmail = schemaEmail.validateAsync.bind(schemaEmail);
|
|
294
|
+
exports.validateActivity = notificationActivitySchema.validateAsync.bind(notificationActivitySchema);
|
|
228
295
|
exports.default = {
|
|
229
296
|
validateReceiver: exports.validateReceiver,
|
|
230
297
|
validateNotification: exports.validateNotification,
|
|
@@ -246,4 +313,9 @@ exports.default = {
|
|
|
246
313
|
optionSchema,
|
|
247
314
|
channelEventSchema,
|
|
248
315
|
NOTIFICATION_TYPES: TYPES,
|
|
316
|
+
ACTIVITY_TYPES,
|
|
317
|
+
ACTIVITY_TARGET_TYPES,
|
|
318
|
+
validateActivity: exports.validateActivity,
|
|
319
|
+
notificationActivitySchema,
|
|
320
|
+
activityTargetSchema,
|
|
249
321
|
};
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.16.41-beta-
|
|
6
|
+
"version": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
7
7
|
"description": "graphql client to read/write data on abt node",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"typings": "lib/index.d.ts",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"author": "linchen1987 <linchen.1987@foxmail.com> (http://github.com/linchen1987)",
|
|
28
28
|
"license": "Apache-2.0",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@abtnode/client": "1.16.41-beta-
|
|
31
|
-
"@abtnode/constant": "1.16.41-beta-
|
|
32
|
-
"@abtnode/util": "1.16.41-beta-
|
|
30
|
+
"@abtnode/client": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
31
|
+
"@abtnode/constant": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
32
|
+
"@abtnode/util": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
33
33
|
"@arcblock/did": "1.19.15",
|
|
34
34
|
"@arcblock/did-auth": "1.19.15",
|
|
35
35
|
"@arcblock/jwt": "1.19.15",
|
|
36
36
|
"@arcblock/ws": "1.19.15",
|
|
37
|
-
"@blocklet/constant": "1.16.41-beta-
|
|
38
|
-
"@blocklet/env": "1.16.41-beta-
|
|
39
|
-
"@blocklet/meta": "1.16.41-beta-
|
|
37
|
+
"@blocklet/constant": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
38
|
+
"@blocklet/env": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
39
|
+
"@blocklet/meta": "1.16.41-beta-20250331-010247-966fcfb0",
|
|
40
40
|
"@did-connect/authenticator": "^2.2.7",
|
|
41
41
|
"@did-connect/handler": "^2.2.7",
|
|
42
42
|
"@nedb/core": "^2.1.5",
|
|
@@ -82,5 +82,5 @@
|
|
|
82
82
|
"ts-node": "^10.9.1",
|
|
83
83
|
"typescript": "^5.6.3"
|
|
84
84
|
},
|
|
85
|
-
"gitHead": "
|
|
85
|
+
"gitHead": "3c7f691205d82118ef5e8d60fbb2dd84fe7b7b7c"
|
|
86
86
|
}
|